C# 首先理解实体框架代码中的ForeignKey属性
有关背景信息,请参阅以下帖子: 我一直认为,C# 首先理解实体框架代码中的ForeignKey属性,c#,entity-framework,foreign-keys,code-first,shared-primary-key,C#,Entity Framework,Foreign Keys,Code First,Shared Primary Key,有关背景信息,请参阅以下帖子: 我一直认为,ForeignKey用于显示类中哪个属性持有决定导航属性的ForeignKey,例如 公共类成员数据集 { [关键] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 公共int Id{get;set;} public int?DeferredDataId{get;set;} [ForeignKey(“DeferredDataId”)] 公共虚拟延迟数据延迟数据{get;se
ForeignKey
用于显示类中哪个属性持有决定导航属性的ForeignKey,例如
公共类成员数据集
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
public int?DeferredDataId{get;set;}
[ForeignKey(“DeferredDataId”)]
公共虚拟延迟数据延迟数据{get;set;}
}
然而,我在链接的帖子上发现,这是不对的,因为DeferredData的主键名为Id,所以我实际上需要:
公共类成员数据集
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
public int?DeferredDataId{get;set;}
[外国钥匙(“Id”)]
公共虚拟延迟数据延迟数据{get;set;}
}
i、 e.ForeignKey
用于指向其他类
然后,我开始更改其他一些参考:
公共类成员数据集
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
public int?DeferredDataId{get;set;}
[外国钥匙(“Id”)]
公共虚拟延迟数据延迟数据{get;set;}
public int?SignedOffById{get;set;}
[外键(“用户ID”)]
公共虚拟用户配置文件SignedOffBy{get;set;}
}
然而,这失败了。在这个例子中,需要使用ForeignKey
来指向MemberDataSet
类上的Id
公共类成员数据集
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
public int?DeferredDataId{get;set;}
[外国钥匙(“Id”)]
公共虚拟延迟数据延迟数据{get;set;}
public int?SignedOffById{get;set;}
[ForeignKey(“SignedOffById”)]
公共虚拟用户配置文件SignedOffBy{get;set;}
}
我认为这是因为第二种关系是一对多,而第一种关系是一对零或一,实际上,这种关系的主要目的是不同的,但我希望能够澄清这一点/引用好的文章,以便我能够理解正在发生的事情以及ForeignKey正在做的事情
我还在上面的例子中寻找如何public int?DeferredDataId{get;set;}
符合等式,因为它没有显式链接到DeferredData
。我很高兴这将符合惯例,但我将如何明确告诉它,例如,如果它有一个不同的名称?我在这篇演讲中看到的所有例子都是关于使用ForeignKey
属性的,但这并不是上述所有情况下的答案
非常感谢所有的帮助-希望了解问题,而不是解决具体问题,因为我的模型中有很多参考资料,所以需要确定对每个问题采取什么方法
谢谢
编辑
添加了其他类以帮助:
公共类延迟数据
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
//其他属性
}
公共类用户配置文件
{
[关键]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId{get;set;}
//其他属性
}
我认为你是对的(前提是我对你的理解是正确的)<代码>[ForeignKeyAttribute]用于共同响应的外键。不在链接对象的主键上
这是我的对象,外键是DeferredDataId
对象中的Id
不是外键(它是主键),链接对象的Id
也不是外键(它是关系另一端的主键)
希望我正确地理解了您:)因为我不确定。1..0关系的必需端
MemberDataSet
不应该有FK toDeferredData
。相反,DeferredData
的主键也应该是MemberDataSet
的FK(称为共享主键)
Fluent API:
modelBuilder.Entity<MemberDataSet>()
.HasOptional( mds => mds.DeferredData )
.WithRequired()
.WillCascadeOnDelete();
modelBuilder.Entity()
.has可选(mds=>mds.DeferredData)
.WithRequired()
.WillCascadeOnDelete();
我认为你最初的想法是正确的,只有一点例外。通过将外键放在MemberDataSet
上,意味着您想要零或一对多关系
在您的示例中,MemberDataSet.DeferredData
是可选的,许多MemberDataSet
实例可以引用DeferredData
在流畅的语法中,这可以表示为:
modelBuilder.Entity<MemberDataSet>()
.HasOptional(dataSet => dataSet.DeferredData)
.WithMany()
.HasForeignKey(deferredData => deferredData.DeferredDataId);
注意:我喜欢这样的描述“这是我的对象,外键是DeferredDataId”。我一直都是这么想的。但是,这无法构建数据库,解决方案是更改为Id,即根据链接的帖子引用其他类。我检查了我的一个旧项目。我就是这样做的(而且成功了)。环境是wcf数据服务,首先是sql ce 4和实体框架代码。但我不认为这有什么关系。您是否收到任何错误?错误是“类型'MemberDataSet'的属性'DeferredData'上的ForeignKeyAttribute无效。在依赖类型'DeferredData'上找不到外键名称'DeferredDataId'。”我想@Moho已经解释了这个问题,并且开始有意义了!我将链接到一篇MSDN文章。在《关系属性:反向属性和外键》一章中,解释就是这样的。另一种方法是对关系属性使用virtual。EF code first将自行创建外键。谢天谢地,我之前读过这篇文章,但我不知道如何将它应用到我所做的事情上
modelBuilder.Entity<MemberDataSet>()
.HasOptional(dataSet => dataSet.DeferredData)
.WithMany()
.HasForeignKey(deferredData => deferredData.DeferredDataId);
CREATE UNIQUE INDEX unique_MemberDataSet_DeferredDataId ON MemberDataSet(DeferredDataId) WHERE DeferredDataId IS NOT NULL