我有这种情况:
public class Member
{
public int MemberID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Comment
{
public int CommentID { get; set; }
public string Message { get; set; }
public virtual ICollection<Member> Members { get; set; }
}
public class MemberComment
{
public int MemberID { get; set; }
public int CommentID { get; set; }
public int Something { get; set; }
public string SomethingElse { get; set; }
}
如何配置与fluent API的关联?或者有更好的方法来创建关联表吗?
6 回答
TLDR; (semi-related to an EF editor bug in EF6/VS2012U5) 如果从DB生成模型,则无法看到属性m:m表:删除两个相关表 - >保存.edmx - >从数据库生成/添加 - >保存 .
对于那些来到这里的人想知道如何获得与EF .edmx文件中显示的属性列的多对多关系(因为它当前不会显示并被视为一组导航属性),并且您生成了这些类从你的数据库表(或MS语言中的数据库优先,我相信 . )
在.edmx中删除有问题的2个表(以获取OP示例,成员和注释),然后通过“从数据库生成模型”再次添加它们 . (即不要尝试让Visual Studio更新它们 - 删除,保存,添加,保存)
然后它将创建一个符合此处建议的第3个表 .
这在首先添加纯多对多关系的情况下是相关的,并且稍后在DB中设计属性 .
这个线程/谷歌搜索没有立即清楚 . 所以只是把它放在那里,因为这是谷歌上的链接#1寻找问题,但首先来自数据库方面 .
无法与自定义连接表创建多对多关系 . 在多对多关系中,EF在内部管理连接表并隐藏 . 它是一个没有模型中的Entity类的表 . 要使用具有其他属性的此类连接表,您必须实际创建两个一对多关系 . 它可能看起来像这样:
如果您现在想要查找成员的所有注释
LastName
= "Smith",例如您可以编写如下查询:...要么...
或者要创建一个名为“Smith”的成员列表(我们假设有多个)以及他们的评论,您可以使用投影:
如果要查找
MemberId
= 1的成员的所有评论:现在,您还可以按联接表中的属性进行筛选(这在多对多关系中是不可能的),例如:筛选成员1中属性为99的所有注释
Something
:由于延迟加载,事情可能会变得更容易 . 如果您已加载
Member
,则应该能够在没有明确查询的情况下获取注释:我想延迟加载会在幕后自动获取评论 .
Edit
只是为了好玩一些例子,更多如何添加实体和关系以及如何在此模型中删除它们:
1)创建该成员的一个成员和两个评论:
2)添加member1的第三条评论:
3)创建新成员并将其与现有注释2相关联:
4)创建现有member2和comment3之间的关系:
5)再次删除这种关系:
6)删除member1及其与评论的所有关系:
这也会删除
MemberComments
中的关系,因为Member
和MemberComments
之间以及Comment
和MemberComments
之间的一对多关系是按惯例设置的级联删除 . 这是因为MemberComment
中的MemberId
和CommentId
被检测为Member
和Comment
导航属性的外键属性,并且由于FK属性的类型为非可空int
,因此需要这种关系最终导致级联删除设置 . 我认为这个模型很有意义 .Excellent 由Slauma回答 .
我将使用流畅的API映射发布代码来执行此操作 .
在
DbContext
派生类上,您可以这样做:它与接受的答案具有相同的效果,采用不同的方法,即更好或更差 .
编辑:我已将CreatedDate从bool更改为DateTime .
编辑2:由于时间不够,我已经从我正在开发的应用程序中找到了一个示例,以确保它有效 .
解决此错误的一种方法是将
ForeignKey
属性放在所需属性的顶部作为外键并添加导航属性 .注意:在
ForeignKey
属性中,在括号和双引号之间,以这种方式放置引用的类的名称 .@Esteban,你提供的代码是对的,谢谢,但不完整,我已经测试过了 . “UserEmail”类中缺少属性:
如果有人有兴趣,我发布我测试过的代码 . 问候
我想提出一个解决方案,可以实现多对多配置的两种风格 .
"catch"是我们需要创建一个以连接表为目标的视图,因为EF验证每个
EntitySet
最多可以映射一次模式的表 .这个答案增加了以前答案中已经说过的内容,并没有覆盖任何这些方法,它 Build 在此基础之上他们 .
该模型:
配置:
上下文:
来自Saluma(@Saluma)answer
这仍然有效......
......但现在也可能......
这仍然有效......
......但现在也可能......
如果要删除成员的评论
如果你想
Include()
成员的评论这一切都像语法糖,但如果你愿意通过额外的配置,它确实会给你一些好处 . 无论哪种方式,您似乎都能够充分利用这两种方法 .