首先是EF代码,具有多个关系的实体

时间:2017-07-05 10:37:36

标签: sqlite ef-code-first entity-framework-6 polymorphism

enter image description here

在这里,您可以看到我想要存储在我的Sqlite数据库中的简化实体结构。我有Graph,其中包含一组GraphElements。我的GraphEdgesNodesLoads组成,它们都是不同的元素。

例如,对于深度优先搜索,每个节点都需要知道其邻居节点。因此我需要NeigborNodes - 列表。对于其他功能,我还需要知道ConnectedElements - 列表。

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

我的模型配置看起来像这样的时刻,当然不起作用。 (我正在使用每种类型的表格(TPT)方法。)

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

我的问题:

     

(A)如何更改模型配置或我的实体以将NeighborNodes存储在我的数据库中?

     

(B)如何更改模型配置或我的实体以将ConnectedElements存储在我的数据库中?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我自己可以找到一个解决方案,我想简单解释一下:

这是一个“多对多”关系的问题,我首先无法实现,因为我总是将其视为“一对多”关系问题。但是当你看到这样的时候,解决它很简单。在当前情况下,您必须按如下方式扩展模型。您必须告诉EF创建两个映射表。这样,您可以将Node和GridElements / NeighborNodes之间的关系存储在名为NodeGridElement各自NodeNeighborNode的单独DB映射表中。

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");
            });
    }
}
相关问题