0

DDDの原則、つまりアトリビュートにアタッチされたバリューオブジェクトでEF6を使用することに苦労しています。私は、モデルを反映してマイグレーションを生成するようには見えず、実際に生産性を上げる代わりにツールと戦っているように感じる。おそらく、NoSQLの実装がより適切であるとすれば、これは私が悩んでいることです。DDDエンティティフレームワークの値のタイプ

私が遭遇した最初のことは、EFエンティティのインターフェイスプロパティのサポートの欠如でした。これを回避するには、それぞれの実装に対してエンティティに具体的なプロパティを追加するが、インタフェースには追加しないでください。私がインターフェースを実装したとき、正しいロジックを返すロジックを追加しました。ポリシーのプロパティを作成するための移行を行うには、これを行う必要がありました。 Fund.LargestBalanceFirstAllocationPolicyとFund.PercentageBasedAllocationPolicyを参照してくださいこれは迷惑です。

質問の現在の煩さと起源はPercentageBasedAllocationPolicy.AllocationValuesプロパティです。私が何をしていても、追加マイグレーションを実行するとき、私はAllocationValuesを表すテーブルやフィールドを取得しません。これは、基本的に、別の値オブジェクトにぶら下がっているDDD値オブジェクトの集合です。

私はモデルとコードが間違っていないと確信していますが、EFはやり続けます。 MongoDBでは、インターフェイスプロパティを扱う際にオブジェクトタイプを実際に文字列に格納し、オブジェクトを再水和する方法を知っています。私は、値の型が(EFでのComplexTypeとしてマーク)任意のテーブルを持っていることはありません

...ちょうど悪のようである、ブロブにここでの問題領域をシリアライズし、今のオブジェクトの上にそれを格納
public interface IFund 
{ 
    Guid Id {get;} 
    string ProperName {get;} 
    IAllocationPolicy AllocationPolicy{get;} 
    void ChangeAllocationPolicy(IAllocationPolicy newAllocationPolicy) 
} 


public class Fund : IFund 
{ 
    public Fund() 
    { 

    } 

    public Fund(Guid id, string nickName, string properName) 
    { 
     Id = id; 
     Nickname = nickName; 
     ProperName = properName; 

     // This is stupid too, but you have to instantiate these objects inorder to save or you get some EF errors. Make sure the properties on these objects are all defaulted to null. 
     LargestBalanceFirstAllocationPolicy = new LargestBalanceFirstAllocationPolicy(); 
     PercentageBasedAllocationPolicy = new PercentageBasedAllocationPolicy(); 

    } 

    public Guid Id { get; private set; } 

    public string ProperName { get; private set; } 


    // Do not add this to the interface. It's here for EF reasons only. Do not use internally either. Use the interface implemention of AllocationPolicy instead 
    public LargestBalanceFirstAllocationPolicy LargestBalanceFirstAllocationPolicy 
    { 
     get; private set; 
    } 

    // Do not add this to the interface. It's here for EF reasons only. Do not use internally either. Use the interface implemention of AllocationPolicy instead 
    public PercentageBasedAllocationPolicy PercentageBasedAllocationPolicy 
    { 
     get; private set; 
    } 


    public void ChangeAllocationPolicy(IAllocationPolicy newAllocationPolicy) 
    { 
     if (newAllocationPolicy == null) throw new DomainException("Allocation policy is required"); 

     var allocationPolicy = newAllocationPolicy as PercentageBasedAllocationPolicy; 
     if (allocationPolicy != null) PercentageBasedAllocationPolicy = allocationPolicy; 

     var policy = newAllocationPolicy as LargestBalanceFirstAllocationPolicy; 
     if (policy != null ) LargestBalanceFirstAllocationPolicy = policy; 
    } 

    public IAllocationPolicy AllocationPolicy 
    { 
     get { 

      if (LargestBalanceFirstAllocationPolicy != null) 
       return LargestBalanceFirstAllocationPolicy; 

      if (PercentageBasedAllocationPolicy != null) 
       return PercentageBasedAllocationPolicy; 

      return null; 
     } 

    } 
} 

public interface IAllocationPolicy 
{ 
    T Accept<T>(IAllocationPolicyVisitor<T> allocationPolicyVisitor); 
} 

public class LargestBalanceFirstAllocationPolicy : IAllocationPolicy 
{ 
    public T Accept<T>(IAllocationPolicyVisitor<T> allocationPolicyVisitor) 
    { 
     return allocationPolicyVisitor.Visit(this); 
    } 
} 

[ComplexType] 
public class PercentageBasedAllocationPolicy : IAllocationPolicy 
{ 
    public PercentageBasedAllocationPolicy() 
    { 
     AllocationValues = new List<PercentageAllocationPolicyInfo>(); 
    } 

    public List<PercentageAllocationPolicyInfo> AllocationValues { get; private set; } 

    public T Accept<T>(IAllocationPolicyVisitor<T> allocationPolicyVisitor) 
    { 
     return allocationPolicyVisitor.Visit(this); 
    } 
} 

[ComplexType] 
public class PercentageAllocationPolicyInfo 
{ 
    public Guid AssetId { get; private set; } 

    public decimal Percentage { get; private set; } 
} 

答えて

0

を検討しています。その理由は、値の型は(定義によって)本当に単なる値であるということです。彼らにはIdがありません(それ以外の場合はenitiesになります)ので、テーブルを作成することはできません。

また、エンティティフレームワークhttps://msdn.microsoft.com/en-us/library/bb738472(v=vs.100).aspxで複雑なタイプの要件を確認すると、複雑なタイプで継承を使用できないことに気付きます。したがって、ここで示したようにエンティティフレームワークで複合型を使用する場合は、プロパティをIAllocationPolicyではなくPercentageBasedAllocationPolicyにする必要があります。

また、自動生成キーを使用してエンティティにすることもできます。