如何在EF中保存关系条目
本文关键字:关系 保存 EF | 更新日期: 2023-09-27 18:11:49
我的数据库中有3个表。
1名为Images, 1名为Tags最后一个表名为ImageTagIds
My Images table有ID和Path
我的标签有ID和短语
和我的ImageTagIds有ID, ImageId和TagId
我希望这些名字有助于使这个自我解释,但有一个1到许多图像表和ImageTagIds之间的关系,其中图像。ID连接ImageTagIds。ImageId
标签表和ImageTagIds之间有一个1到1的关系,其中标签。Id连接ImageTagIds。Id
我在SSMS中添加了一个数据库图,并创建了所有的键和关系。
在VS 2012中,我创建了一个新的EF (.edmx)文件,并添加了我的表。VS做了一些巫术,我现在可以把我的桌子作为对象。这工作得很好,我可以查询和保存没有异常。我的问题是如何建立关系。
这是我得到的长度
private Dal.MyEntities _dc = new MyEntities();
public void Save(string filePath, IList<string> tags)
{
FileInfo fi = new FileInfo(filePath);
this._dc.Images.Add(new Image()
{
Path = fi.DirectoryName
});
foreach (var tag in tags)
{
this._dc.Tags.Add(new Tag()
{
Phrase = tag
});
}
_dc.SaveChanges();
}
上面的内容保存到Tags表和Image表中,但是ImageTagIds表仍然为空。我知道为什么,我从来没有试图给它写信,但这就是我迷失的地方。我不知道我可以写/代码到ImageTagsId表。
更多的研究引导我到http://www.entityframeworktutorial.net/entity-relationships.aspx,这说(我认为)EF应该知道关系在哪里。即使是这样,我也不知道我可以保存什么/如何保存,因为当我向数据库添加新条目时,我不知道ID将是什么。
您正在添加标签,您正在添加图像,但您没有向图像添加标签。
试试下面的
.Tags_dc.Images.FirstOrDefault()。Add(new Tag() {Phrase = "something"});
从实体的角度来看,这将为特定的图像添加一个标签。从db表的角度来看,它会将标签添加到Tags
表和ImageTagIds
表中。
EDIT:如果你没有Tags
属性,你应该首先确保你的数据库关系是正确的。如果不是这样,您可以尝试
TagsImagesIds tagImageRelation = new TagsImagesIds();
tagImageRelation.ImageId = image.Id;
tagImage.Relation.TagId = tag.Id;
_dc.TagsImagesIds.Add(tagImageRelation);
通常你在图像中缺少Tags
属性的原因是你有更多的列在你的表中,而不是TagId和ImageId,所以EF创建3个类来代表你的表,而不是2。
这是一个多对多关系,用一个具有附加属性的连接表实现(键的定义与EF期望的多对多关系不匹配)。在这种情况下,EF将连接表视为任何其他实体,因此您必须自己创建并保存该表的条目。参见底部关于多对多EF关系的说明
如果您的ImagetTagId
具有以下内容:
- 一个关系,一个指向
Image
的导航属性 - 关系,以及
Tag
的导航属性
和ID是数据库生成的(identity),那么您只需创建所有必要的ImageTagId
对象并设置导航属性。当您调用SaveChanges
时,DbContext将进行关系修复,在ImageTagId
对象中设置正确的id并将它们保存到数据库中。
应该是这样的:
Image img = new Image()
{
Path = fi.DirectoryName
};
this._dc.Images.Add(img);
foreach (var tag in tags)
{
Tag tag = new Tag()
{
Phrase = tag
};
this._dc.Tags.Add();
ImageTagId = new ImageTagId { Image = image, Tag = tag };
this._dc.ImageTagIds.Add(ImageTagId);
}
显然你不能做的是在ImageTagId
中设置id,因为它们在保存之前是不可用的。这就是为什么有必要为Tag
和Image
设置导航属性。
当您调用SaveChanges
时,图像被保存到db中,并获得其db生成的id。保存每个标记时也会发生同样的情况。并且,当保存每个ImageTagId
时,因为它与已经具有id的标签和图像相关,EF复制这些id,并将"固定"对象保存到DB。请在MSDN:关系和导航属性上阅读本文,特别注意一节同步fk和导航属性之间的更改。
如果你想在EF上定义一个纯多对多关系,你需要一个只有
的连接表- 一个FK到多对多面之一
- 一个FK到另一边
- 由两个FKs组成的PK
在您的特殊情况下,您应该有一个表,它只有一个Id是FK到Image,另一个Id是FK到Tag,以及一个由两个FK组成的主键。
当您使用EF多对多关系时,连接表在模型中不作为实体出现。相反,您只有从一侧到另一侧集合的导航属性。在您的特定侧,您将在标签上有一个图像集合,在图像上有一个标签集合。
如果像这样实现多对多,那么连接表项将由EF自动管理。