Entity Framework 中是否有自动关联?
Are there Automatic Associations in Entity Framework?
我似乎记得(也许记错了)DLinq 提供了自动关联。我似乎找不到如何在 EF 中启用或完成此操作。
示例:
public partial class Person
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Clan Clan { get; set; }
}
public partial class Clan
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
如果这些是我的实体,那么我想执行这样的操作:
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.Clan = c;
ASSERT( c.People.First() == p )
或者
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
c.People.Add(p);
ASSERT( p.Clan == c )
此外,如果我使用了 c.People.Add
方法,它应该检查 p.Clan
是否已经引用了不同的氏族,如果是,则将其从该氏族的人员集合中删除。
在 DLINQ 中,我相信他们使用 EntitySet 和 EntityRef 来完成此任务。 Entity Framework 中是否存在等效项?
非常感谢!
有很多方法可以做到这一点。最简单的方法是将 ClanId 属性 添加到您的 Person class 然后使用:
public partial class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int ClanId {get; set;} // You might need to make it virtual. Not sure.
public virtual Clan Clan { get; set; }
}
public partial class Clan
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
这将指示 EF 通过名称 ClanId 创建一个外键。然后您就可以使用以下语法:
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.ClanId = X; // Replace X by a suitable Id.
ASSERT( c.People.First() == p )
想法是确保正确创建外键关系。 EF 能够多次推断出这一点,尤其是在一对多关系中,但在某些情况下却不能。像这样明确指定它将使其在所有情况下都有效。
当您尝试将新人与现有氏族相关联时,这还有其他好处。在某些情况下,EF 认为氏族是新的并尝试插入它。使用这种方法,您将不会遇到这个问题。
另一种方法是在重写的 OnModelCreating 方法中明确指定外键关系。
我在 LINQ-toSQL(以前称为 DLINQ)中尝试了您的代码,但断言永远不会通过。明显的原因是上下文甚至不知道新对象,所以它不可能将它们关联起来。但是,即使您将对象插入上下文 c.People
也不会被填充
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.Clan = c;
context.People.InsertOnSubmit(p);
context.Clans.InsertOnSubmit(c);
ASSERT( c.People.First() == p ) // Still no items in c.People
即使在 SubmitChanges
之后,c.People
也没有任何项目。只有当您在新的上下文中从数据库中重新获取新的 Clan
时,c.People
才会通过延迟加载来加载。所以这些 "automatic associations" 在 LINQ-to-SQL.
中不存在
在 Entity Framework 中有一个名为 relationship fixup 的进程运行 very frequently。在此过程中,EF 扫描主键值和外键值,并在它们匹配时填充导航属性(如 c.People
)。
如果你在 EF 中做同样的事情:
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.Clan = c;
context.People.Add(p); // Also adds c to the context
...Add
方法将触发 DetectChanges
,进而触发关系修复,并且
ASSERT( c.People.First() == p )
...现在将通过。
我似乎记得(也许记错了)DLinq 提供了自动关联。我似乎找不到如何在 EF 中启用或完成此操作。
示例:
public partial class Person
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Clan Clan { get; set; }
}
public partial class Clan
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
如果这些是我的实体,那么我想执行这样的操作:
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.Clan = c;
ASSERT( c.People.First() == p )
或者
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
c.People.Add(p);
ASSERT( p.Clan == c )
此外,如果我使用了 c.People.Add
方法,它应该检查 p.Clan
是否已经引用了不同的氏族,如果是,则将其从该氏族的人员集合中删除。
在 DLINQ 中,我相信他们使用 EntitySet 和 EntityRef 来完成此任务。 Entity Framework 中是否存在等效项?
非常感谢!
有很多方法可以做到这一点。最简单的方法是将 ClanId 属性 添加到您的 Person class 然后使用:
public partial class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int ClanId {get; set;} // You might need to make it virtual. Not sure.
public virtual Clan Clan { get; set; }
}
public partial class Clan
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> People { get; set; }
}
这将指示 EF 通过名称 ClanId 创建一个外键。然后您就可以使用以下语法:
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.ClanId = X; // Replace X by a suitable Id.
ASSERT( c.People.First() == p )
想法是确保正确创建外键关系。 EF 能够多次推断出这一点,尤其是在一对多关系中,但在某些情况下却不能。像这样明确指定它将使其在所有情况下都有效。
当您尝试将新人与现有氏族相关联时,这还有其他好处。在某些情况下,EF 认为氏族是新的并尝试插入它。使用这种方法,您将不会遇到这个问题。
另一种方法是在重写的 OnModelCreating 方法中明确指定外键关系。
我在 LINQ-toSQL(以前称为 DLINQ)中尝试了您的代码,但断言永远不会通过。明显的原因是上下文甚至不知道新对象,所以它不可能将它们关联起来。但是,即使您将对象插入上下文 c.People
也不会被填充
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.Clan = c;
context.People.InsertOnSubmit(p);
context.Clans.InsertOnSubmit(c);
ASSERT( c.People.First() == p ) // Still no items in c.People
即使在 SubmitChanges
之后,c.People
也没有任何项目。只有当您在新的上下文中从数据库中重新获取新的 Clan
时,c.People
才会通过延迟加载来加载。所以这些 "automatic associations" 在 LINQ-to-SQL.
在 Entity Framework 中有一个名为 relationship fixup 的进程运行 very frequently。在此过程中,EF 扫描主键值和外键值,并在它们匹配时填充导航属性(如 c.People
)。
如果你在 EF 中做同样的事情:
var p = new Person() { Name = "Tom" };
var c = new Clan() { Name = "SomeClan" };
p.Clan = c;
context.People.Add(p); // Also adds c to the context
...Add
方法将触发 DetectChanges
,进而触发关系修复,并且
ASSERT( c.People.First() == p )
...现在将通过。