繁体   English   中英

如何在EF中保存关系条目

[英]How to save relational entries in EF

我的数据库中有3个表。

1个称为图像,1个称为标签,最后一个表称为ImageTagIds

我的图像表具有ID和路径

我的标签有ID和词组

我的ImageTagIds具有ID,ImageId和TagId

我希望这些名称有助于自我解释,但是Image表和ImageTagIds之间存在一对多的关系,其中Image.ID连接到ImageTagIds.ImageId

Tag表和ImageTagIds之间存在一对一的关系,其中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是什么。

您正在添加标签,并且正在添加图像,但没有在图像中添加标签。

尝试以下

_dc.Images.FirstOrDefault()。Tags.Add(new Tag(){短语=“某物”});

从实体的角度来看,这将为特定图像添加标签。 从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。

这是一个多对多关系,是通过具有附加属性的联结表实现的(并且键的定义与EF对多对多关系的期望不匹配)。 在这种情况下,EF将联结表视为其他任何实体,因此您必须自己创建条目并将其保存到该表中。 请参阅底部有关多对五关系的注释

ImagetTagId是您的ImagetTagId具有以下内容:

  • 关系, Image的导航属性
  • 关系和Tag导航属性

并且ID是数据库生成的(身份),则只需创建所有必要的ImageTagId对象并设置导航属性。 当您调用SaveChanges ,DbContext将进行关系ImageTagId ,在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,因为它们只有在保存后才可用。 这样一来,就必须具有TagImage的导航属性。

调用SaveChanges ,图像将保存到数据库,并获取其数据库生成的ID。 保存每个标签时也会发生同样的情况。 并且,当保存每个ImageTagId ,由于它与已经具有id的标签和图像相关,因此EF复制这些ID,然后将“ fixed-up”对象保存到DB。 在MSDN上阅读此文章: 关系和导航属性 ,特别注意同步FK和导航属性之间的更改部分。

EF中的多对多关系

如果要在EF上定义纯多对多关系,则需要仅具有

  • 一个FK到多对多边之一
  • 另一边的FK
  • 由两个FK组成的PK

在您的特定情况下,您应该有一个表,该表仅具有一个ID(从FK到图像),另一个ID(从FK到Tag)以及由两个FK组成的主键。

当您使用EF多对多关系时,联结表在模型中不会显示为完整。 相反,您只有从每一侧到另一侧的集合的导航属性。 在您的特定方面,您会在Tag上有一个Images集合,在Image上有一个Tags集合。

如果您像这样实现了很多,则联结表条目将由EF自动管理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM