问题
I'm trying to save a graph into a database as described here with EF Code First.
I defined property with collection of adjacent nodes:
public class Node {
public int NodeId { get; set; }
public string NodeName { get; set; }
public ICollection<Node> Nodes { get; set; }
}
but EF generated only one table for this model:
dbo.Nodes
NodeId (PK, int, not null)
NodeName (nvarchar(max), null)
Node_NodeId (FK, int, null)
How to force EF to generate many-to-many relationship?
Are there any other ways to store graphs in the database?
回答1:
Your class model expresses that a Node
has one collection of nodes, which can be fully accommodated by the generated table. If you want many-to-many, you'll have to tell EF about your plans.
One thing you can do is make parent and child collections:
public class Node
{
public int Id { get; set; }
public string NodeName { get; set; }
public ICollection<Node> ParentNodes { get; set; }
public ICollection<Node> ChildNodes { get; set; }
}
EF will create a join table as follows:
[dbo].[NodeNodes]
[Node_Id] [int] NOT NULL,
[Node_Id1] [int] NOT NULL
If you want more meaningful names of the columns you could do this:
class NodeContext : DbContext
{
public DbSet<Node> Nodes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Node>()
.HasMany(n => n.ParentNodes)
.WithMany(n => n.ChildNodes)
.Map(c => c.MapLeftKey("ChildNodeId")
.MapRightKey("ParentNodeId"));
}
}
Try this:
var root = new Node { NodeName = "Root" };
root.ParentNodes = new List<Node> { new Node { NodeName = "Par1" }, new Node { NodeName = "Par2" } };
root.ChildNodes = new List<Node> { new Node { NodeName = "Ch1" }, new Node { NodeName = "Ch2" } };
con.Nodes.Add(root);
con.SaveChanges();
(Where con
is a NodeContext
instance) and see if you like the result.
来源:https://stackoverflow.com/questions/9653861/storing-graph-with-ef-code-first