0

次のリポジトリがあります。ファクトリを使用して、LINQ2SQLで生成されたクラスとドメインオブジェクトの間のマッピングがあります。

次のコードが機能します。しかし、私は2つの潜在的な問題を見ています

1)更新ステートメントの前にSELECTクエリを使用しています。

2)すべての列(変更された列だけでなく)を更新する必要があります。これは、ドメインオブジェクトで変更されたすべての列がわからないためです。

これらの欠点を克服する方法は?

注:特定の列の更新に基づいて実行されるシナリオ(トリガーなど)が存在する可能性があります。そのため、列を不必要に更新することはできません。

参照

  1. LINQ to SQL:「UpdateCheck=Never」の場合に更新せずに更新する</a>

  2. http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=113917

コード

namespace RepositoryLayer
{
public interface ILijosBankRepository
{      
    void SubmitChangesForEntity();
}

public class LijosSimpleBankRepository : ILijosBankRepository
{

    private IBankAccountFactory bankFactory = new MySimpleBankAccountFactory();
    public System.Data.Linq.DataContext Context
    {
        get;
        set;
    }


    public virtual void SubmitChangesForEntity(DomainEntitiesForBank.IBankAccount iBankAcc)
    {
        //Does not get help from automated change tracking (due to mapping)

        //Selecting the required entity
        DBML_Project.BankAccount tableEntity = Context.GetTable<DBML_Project.BankAccount>().SingleOrDefault(p => p.BankAccountID == iBankAcc.BankAccountID);

        if (tableEntity != null)
        {
            //Setting all the values to updates (except primary key)
            tableEntity.Status = iBankAcc.AccountStatus;

            //Type Checking
            if (iBankAcc is DomainEntitiesForBank.FixedBankAccount)
            {
                tableEntity.AccountType = "Fixed";
            }

            if (iBankAcc is DomainEntitiesForBank.SavingsBankAccount)
            {
                tableEntity.AccountType = "Savings";
            }

            Context.SubmitChanges();
        }
    }
}

}

namespace DomainEntitiesForBank
{

public interface IBankAccount
{
    int BankAccountID { get; set; }
    double Balance { get; set; }
    string AccountStatus { get; set; }
    void FreezeAccount();

}

public class FixedBankAccount : IBankAccount
{

    public int BankAccountID { get; set; }
    public string AccountStatus { get; set; }
    public double Balance { get; set; }

    public void FreezeAccount()
    {
        AccountStatus = "Frozen";
    }
}


}
4

2 に答える 2

1

これは実際にはDDDの質問ではありません。私があなたが尋ねていると言うことができることから:

linqを使用して、選択せずに直接更新を生成します

受け入れられた回答が不可能だった場合でも、データコンテキストの変更追跡を開始するためにオブジェクトをコンテキストにアタッチできることを示唆する、より高い投票数の回答があります。

トリガーの無効化に関する2番目のポイントは、ここここで回答されています。しかし、他の人がコメントしているように、あなたは本当にトリガーが必要ですか?これらの更新をコードで制御するべきではありませんか?

一般的に、あなたは時期尚早の最適化を見ていると思います。あなたはORMを使用しており、その一環として、データベースの配管に関する決定を行うためにL2Sを信頼しています。ただし、必要に応じて、ストアドプロシージャを使用して特定のSQLを実行できることを覚えておいてください。

于 2012-06-30T06:24:52.073 に答える
1

私があなたの質問を理解した場合、元の値が何であったか、またはどの列が実際に変更されたかを知らずにデータベースに保存する必要があるエンティティが渡されています。

その場合は、4つのオプションがあります

  1. データベースに戻って元の値を確認する必要があります。つまり、コードの実行中に選択を実行する必要があります。これにより、すべてのエンティティ値を設定でき、Linq2Sqlが実際に変更された列を処理します。したがって、実際に変更された列がない場合、更新ステートメントはトリガーされません。

  2. 選択を避けて、列を更新する必要があります。あなたはすでにその方法を知っています(しかし他の人はこの質問と答えを見てください)。どの列が変更されたかわからないため、オプションはありませんが、すべてを設定します。これにより、実際に列が変更されていない場合でも更新ステートメントが生成され、データベーストリガーがトリガーされる可能性があります。トリガーを無効にすることは別として、ここでできることは、トリガーが古い列と新しい列の値をチェックして不要な更新を回避するように作成されていることを確認することだけです。

  3. 古いエンティティ値と新しいエンティティ値の両方が必要になるように要件/プログラムを変更する必要があります。これにより、データベースに戻らずに、変更された列を特定できます。

  4. 更新にLINQを使用しないでください。LINQはLanguageIntegratedQUERYの略で、クエリでは(IMHO)優れていますが、更新/削除機能を追加のボーナスとして常に見ていましたが、それが設計されたものではありませんでした。また、タイミング/パフォーマンスが重要な場合、LINQが適切に手作りされたSQLと一致する方法はありません。

于 2012-06-30T11:09:19.320 に答える