状況:私は '永続性レイヤー'としてLinqToSql(無関係と見なすことができます)を使用しており、問題のあるビジネス関連のロジックがどこに行くべきかに関するアーキテクチャ上の懸念を解決しようとしています。永続性の前にリレーションシップ作成を必要とするエンティティ挿入のために私のコードはどこにあるべきですか?
シナリオ:アプリケーションのユーザーが新しい注文を作成します。彼らがそうするとき、プロダクトキーの集まりはその注文と関連付けられる必要があります。
私の最初の試みは、このジャズのすべてをOrderServiceクラスに入れることでした。
partial void InsertOrder(Order instance)
{
var productKeys = this.ProductKeys
.Where(x => x.DeleteDate == null && x.Order == null && !x.Issued)
.Take(instance.NumberOfProductKeys);
if (productKeys.Count() != instance.NumberOfProductKeys)
throw new NotSupportedException("There needs to be more product keys in the database.");
instance.ProductKeys.AddRange(productKeys);
this.ExecuteDynamicInsert(instance);
}
が意図したとおり、これは動作しないという事実を無視(プロダクトキーが実際に順番に関連付けされることはありません)、私はと感じて:その後、私は部分的なメソッドを使用して、私のDataContextのでそれを組み込むことを試みこれは私のビジネスドメインから論理をはずし、それを私の「永続性レイヤー」にプッシュします。私はOrderServiceクラスに入れることも考えましたが、ドメインエンティティからロジックを取り除き、トランザクションスクリプトを作成しただけであると感じました。 Order Factoryを導入するだけで、問題が回避されます。データとロジックが再び分離されます。
貧血のドメインモデルを避け、栄光のあるデータ構造の他に何かをして欲しいと思っても、このロジックを私のドメインモデルに統合する適切な方法はありますか?
public partial class Order
{
public void AssociateWithProductKeys(WIIIPDataContext context)
{
var productKeys = context.ProductKeys
.Where(x => x.DeleteDate == null && !x.Issued && x.Order == null && x.ProductType == ProductType)
.Take(NumberOfProductKeys);
if (productKeys.Count() != NumberOfProductKeys)
throw new ValidationException("There needs to be more product keys in the database for product type: " + ProductType.Description);
ProductKeys.AddRange(productKeys);
foreach (ProductKey productKey in ProductKeys)
{
productKey.Issued = true;
}
}
partial void OnValidate(ChangeAction action)
{
if (action == ChangeAction.Insert)
{
if (ProductType.Id == 3 && ProductKeys.Count() != 1)
throw new ValidationException("Attempted to associated more than 1 product key with a CD version.");
if (ProductKeys.Count() != NumberOfProductKeys)
throw new ValidationException("Number of product keys doesn't match expected value");
}
}
}
ので、次のようになり、コードの消費:
を私はまだ出ている最善の解決策は、Orderクラスにロジックを入れて、それが検証フックで行われたことを確認することです
// The Unit of Work
using (var context = new MyDataContext())
{
...
order.AssociateWithProductKeys(context);
context.Orders.InsertOnSubmit(order);
context.SubmitChanges();
}
==もはや更新LinqToSQL(およびWebフォーム)を使用しているとき、私は、コマンド/クエリパターンを採用している2012年3月29日==
とLinqToSqlによって作成されたエンティティを使用私のデータストアへのマッピング以外のものとしてのDataContext。すべての私のルールと、コマンドオブジェクトに入るものは、アプリケーションの真の核となっています。
私は何かを理解していません。どの層、ロジック、またはデータが、永続化する前に注文に関連付けるためにDB内の製品を見つけようとしますか?注文に既に関連する商品が含まれていてはなりませんか?私はクライアントが注文と製品を関連づけ、ロジッククラスはルール違反を検証し、DALは単にドメインエンティティをDBエンティティ/テーブルにマッピングし、それを永続させると思います。いいえ? –
クライアントは、プロダクトキーをオーダーに関連付ける責任を負いません。クライアントが注文を作成するときに、必要なキーの数を指定します。これらのキーを割り当てるのはシステムです。それは問題の中心です:その割り当て論理はどこに行き、その本質は何か:ビジネスかそうでなければ何ですか? – Merritt
ああ、あなたは鍵の割り当てについて話しています。はい。したがって、クライアントはプロダクトキーの数を選択しますが、実際のプロダクトは選択しません。クライアントが注文のためにプロダクトを選んだ場合、そのキーは既にエンティティ内に存在するはずです。それはクライアントが見ることができないはずですが、にもかかわらず存在するはずです。 –