0

Я борюсь с использованием EF6 с принципами DDD, а именно объектами ценности, привязанными к агрегатам. Кажется, я не могу заставить миграции генерировать, которые отражают модель, и я чувствую, что я сражаюсь с инструментами вместо того, чтобы фактически быть продуктивным. Учитывая, что реализация NoSQL, вероятно, более уместна, вот что я застрял.DDD Entity Framework Значение Тип

Первое, на что я столкнулся, - отсутствие поддержки свойств интерфейса для объекта EF. Работа для этого заключалась в том, чтобы добавлять конкретные объекты к объекту для каждой из реализаций, но не к интерфейсу. Когда я реализовал интерфейс, я добавил логику, чтобы вернуть правильный. Я должен был сделать это, чтобы получить какие-либо миграции для создания свойств для Политики. См. Fund.LargestBalanceFirstAllocationPolicy и Fund.PercentageBasedAllocationPolicy. Это было неприятно.

Текущее раздражение и генезис вопроса - свойство PercentageBasedAllocationPolicy.AllocationValues. Независимо от того, что я делаю, при запуске add-migration я не получаю никаких таблиц или полей для представления AllocationValues. Это в основном набор объектов значения DDD, зависающих от другого объекта значения, который зависает от агрегата.

Я убежден, что модель и код правильны, чтобы делать то, что я хочу, но EF продолжает мешать. В MongoDB, когда он имеет дело с интерфейсом, он фактически сохраняет тип объекта в строке, чтобы он знал, как регидратировать объект. Я рассматриваю сериализации проблемных областей здесь в сгусток и хранить его на объект в настоящее время, который так же, как зло ...

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

типа значения (в EF помечен как ComplexType) никогда не будет иметь никаких таблиц , Причина в том, что типы значений (по определению) действительно справедливы. У них нет Id (иначе они были бы enities), поэтому вы не можете создать таблицу для них.

также, если я рассмотрю требования к сложному типу в структуре сущности https://msdn.microsoft.com/en-us/library/bb738472(v=vs.100).aspx Я замечаю, что вы не можете использовать наследование сложных типов. Таким образом, если вы хотите использовать сложный тип в своей инфраструктуре сущности, как вы показали здесь, вам нужно сделать свой объект PercentageBasedAllocationPolicy вместо IAllocationPolicy.

В качестве альтернативы вы можете превратить его в объект с автоматическими сгенерированными ключами.

Смежные вопросы