我的数据库中有3个表。
1个名为Images,1个名为Tags,最后一个名为ImageTagIds
我的图片表有ID和路径
我的标签有ID和短语
我的ImageTagIds有ID,ImageId和TagId
我希望这些名称有助于自我解释,但Image表和ImageTagIds之间存在1对多的关系,其中Image.ID连接到ImageTagIds.ImageId
Tag表与ImageTagIds之间存在1对人的关系,其中Tag.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将会是什么。
答案 0 :(得分:1)
您正在添加标签,但您正在添加图片,但您没有为图片添加标签。
尝试以下
_dc.Images.FirstOrDefault()。Tags.Add(new Tag(){Phrase =&#34; something&#34;});
从实体的角度来看,这将为特定图像添加标签。
从db表的角度来看,它会将标记添加到Tags
表和ImageTagIds
表中。
编辑:如果您没有Tags
属性,首先应确保正确建立数据库关系。如果不是这样,你可以尝试
TagsImagesIds tagImageRelation = new TagsImagesIds();
tagImageRelation.ImageId = image.Id;
tagImage.Relation.TagId = tag.Id;
_dc.TagsImagesIds.Add(tagImageRelation);
通常,您缺少图像中Tags
属性的原因是您的表中除了TagId和ImageId之外还有更多列,因此EF会创建3个类来表示您的表而不是2个。
答案 1 :(得分:1)
这是一个多对多关系,使用具有附加属性的联结表实现(并且密钥的定义与EF对多对多关系的预期不匹配)。在这种情况下,EF将联结表视为任何其他实体,因此您必须自己创建并将条目保存到此表。 请参阅底部的多对多EF关系的说明
如果您的ImagetTagId
具有以下内容:
Image
Tag
并且ID是数据库生成的(标识),然后您只需创建所有必需的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
时,图像将保存到数据库,并获取其数据库生成的ID。保存每个标签时也会发生同样的情况并且,在保存每个ImageTagId
时,因为它与标签和已有ID的图像相关,EF复制这些ID,并将“修复”对象保存到DB。在MSDN上阅读此内容:Relationships and Navigation Properties,特别注意同步FK和导航属性之间的更改部分。
EF中的多对多关系
如果要在EF上定义纯多对多关系,则需要只有
的联结表在您的特定情况下,您应该有一个表只有一个ID是FK到Image,另一个Id是FK到Tag,以及一个主键由两个FK组成。
当您使用EF多对多关系时,联结表在模型中不会显示为entiy。相反,您只有从每一侧到另一侧的集合的导航属性。在您的特定方面,您在Tag上有一个Images集合,在Image上有一个Tags集合。
如果像这样阻止多对多,联结表条目将由EF自动管理。