EF code first, Entities with multiple relations

蹲街弑〆低调 提交于 2020-03-06 04:16:34

问题


Here you can see my reduced entity structure which I would like to store in my Sqlite database. I've a Graph which holds a Set of GraphElements. My Graph consists of Edges, Nodes and Loads which are all different Elements.

For a deep-first-search for example each node needs to know its neighbor nodes. Therefore I need the NeigborNodes-List. For other functionalities I need also to know the ConnectedElements-List.

class Graph
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual List<GraphElement> GraphElements { get; set; }
}

[Table("GraphElements")]
abstract class GraphElement
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Graph Graph { get; set; }
}

[Table("Nodes")]
class Node : GraphElement
{
    public virtual List<Node> NeighborNodes { get; set; }
    public virtual List<GraphElement> ConnectedElements { get; set; }
}

[Table("Edges")]
class Edge : GraphElement
{
    public virtual Node From { get; set; }
    public virtual Node To { get; set; }
}

[Table("Loads")]
class Load : GraphElement
{
    public virtual Node From { get; set; }
}

My model configuration looks at the moment like this and is of course not working. (I'm working with the Table per Type (TPT) approach.)

public class ModelConfiguration
{
    private static void ConfigureGridDataCollectionEntity(DbModelBuilder modelBuilder)
    {
        // Graph
        modelBuilder.Entity<Graph>().ToTable("Base.GraphTable")
             .HasRequired(p => p.GraphElements)
             .WithMany()
             .WillCascadeOnDelete(true);

        // GraphElement
        modelBuilder.Entity<GraphElement>()
           .HasRequired(p => p.Graph)
           .WithMany(graph => graph.GraphElements)
           .WillCascadeOnDelete(false);

        // Edge
        modelBuilder.Entity<Edge>()
           .HasOptional(p => p.From)
           .WithMany(node => node.ConnectedElements) // Convertion error
           .WillCascadeOnDelete(false);

        modelBuilder.Entity<Edge>()
           .HasOptional(p => p.To)
           .WithMany(node => node.ConnectedElements) // Convertion error
           .WillCascadeOnDelete(flase);

        // Load
        modelBuilder.Entity<Load>()
           .HasOptional(p => p.From)
           .WithMany(node => node.ConnectedElements) // Convertion error
           .WillCascadeOnDelete(false);

        // Node
        // No idea at all...
    }
}

My question:

(A) How can I change my model configuration or my entities to store NeighborNodes in my database?

(B) How can I change my model configuration or my entities to store ConnectedElements in my database?

Thank you for the help!


回答1:


I could find a solution myself which I would like to explain briefly:

It is a matter of a “Many to Many” relationship what I was not able to realize in the first place because I always saw it as a “One to Many” relationship problem. But when you see it like this, it’s pretty simple to solve it. In the current case, you have to extend the model as follows. You have to tell EF to create two mapping tables. This way you can store the relationship between the Node and the GridElements/NeighborNodes in separate DB-mapping-tables called NodeGridElement respectiveNodeNeighborNode.

public class ModelConfiguration
{
    private static void ConfigureGridDataCollectionEntity(DbModelBuilder modelBuilder)
    {
        // Graph
        modelBuilder.Entity<Graph>().ToTable("Base.GraphTable")
             .HasRequired(p => p.GraphElements)
             .WithMany()
             .WillCascadeOnDelete(true);

        // GraphElement
        modelBuilder.Entity<GraphElement>()
           .HasRequired(p => p.Graph)
           .WithMany(graph => graph.GraphElements)
           .WillCascadeOnDelete(false);

        // Node
        modelBuilder.Entity<Node>()
            .HasMany(p => p.ConnectedElements)
            .WithMany()
            .Map(cs =>
            {
                cs.MapLeftKey("NodeId");
                cs.MapRightKey("GridElementId");
                cs.ToTable("NodeGridElement");
            });

        modelBuilder.Entity<Node>()
            .HasMany(p => p.NeighborNodes)
            .WithMany()
            .Map(cs =>
            {
                cs.MapLeftKey("NodeId");
                cs.MapRightKey("NeighborNodeId");
                cs.ToTable("NodeNeighborNode");
            });
    }
}


来源:https://stackoverflow.com/questions/44923891/ef-code-first-entities-with-multiple-relations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!