0

Ich habe Probleme mit der Verwendung von EF6 mit DDD-Prinzipien, nämlich Wertobjekte an Aggregaten angehängt. Ich kann anscheinend keine Migrationen generieren, die das Modell widerspiegeln, und ich habe das Gefühl, dass ich gegen die Werkzeuge ankämpfe, anstatt produktiv zu sein. Angesichts der Tatsache, dass eine NoSQL-Implementierung wahrscheinlich besser geeignet ist, stehe ich fest.DDD Entity Framework Wert Typ

Die erste Sache, die ich lief, war die fehlende Unterstützung für Schnittstelleneigenschaften auf einer EF-Einheit. Die Arbeit dafür bestand darin, der Entität für jede der Implementierungen konkrete Eigenschaften hinzuzufügen, nicht jedoch für die Schnittstelle. Als ich die Schnittstelle implementierte, fügte ich Logik hinzu, um die richtige zurückzugeben. Ich musste dies tun, um Migrationen zu erhalten, um die Eigenschaften für die Richtlinien zu erstellen. Siehe Fund.LargestBalanceFirstAllocationPolicy und Fund.PercentageBasedAllocationPolicy Dies war ein Ärgernis.

Die aktuelle Belästigung und die Entstehung der Frage ist die PercentageBasedAllocationPolicy.AllocationValues-Eigenschaft. Unabhängig davon, was ich mache, bekomme ich beim Ausführen von add-migration keine Tabellen oder Felder zur Darstellung der AllocationValues. Dies ist im Grunde eine Sammlung von DDD-Wertobjekten, die von einem anderen Wertobjekt hängen, das an einem Aggregat hängt.

Ich bin überzeugt, dass das Modell und der Code korrekt sind, um zu tun, was ich will, aber EF stört mich immer. Wenn es sich um eine Schnittstelleneigenschaft handelt, speichert MongoDB den Objekttyp tatsächlich in einer Zeichenfolge, sodass er weiß, wie das Objekt rehydriert wird. Ich betrachte die Problembereiche hier zu einem Blob Serialisierung und für das Objekt speichert nun, die ebenso böse ist ...

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; } 
} 

Antwort

0

Ein Wert-Typ (in EF als Complex markiert) wird nie irgendwelche Tabellen . Der Grund dafür ist, dass Werttypen (per Definition) wirklich nur Werte sind. Sie haben keine ID (sonst wären sie enities), also können Sie keine Tabelle für sie erstellen.

auch, wenn ich die Anforderungen für komplexe Art in Entity Framework https://msdn.microsoft.com/en-us/library/bb738472(v=vs.100).aspx überprüfen, merke ich, dass Sie keine Vererbung für komplexe Typen verwenden können. Wenn Sie also einen komplexen Typ in Ihrem Entitätsframework verwenden möchten, wie Sie es hier gezeigt haben, müssen Sie Ihre Property zu einer PercentageBasedAllocationPolicy anstelle einer IAlocationPolicy machen.

Alternativ können Sie es in eine Entität mit automatisch generierten Schlüsseln verwandeln.

Verwandte Themen