简体   繁体   English

如何在EF中保存关系条目

[英]How to save relational entries in EF

I have 3 tables in my database. 我的数据库中有3个表。

1 called Images, 1 called Tags and the last table is called ImageTagIds 1个称为图像,1个称为标签,最后一个表称为ImageTagIds

My Images table has ID and Path 我的图像表具有ID和路径

My Tags has ID and Phrase 我的标签有ID和词组

and my ImageTagIds has ID, ImageId and TagId 我的ImageTagIds具有ID,ImageId和TagId

I'm hoping the names help to make this self explaining but there is a 1 to many relationship between Image table and ImageTagIds, where Image.ID joins on ImageTagIds.ImageId 我希望这些名称有助于自我解释,但是Image表和ImageTagIds之间存在一对多的关系,其中Image.ID连接到ImageTagIds.ImageId

There is a 1 to man relationship between Tag table and ImageTagIds where Tag.Id joins on ImageTagIds.Id Tag表和ImageTagIds之间存在一对一的关系,其中Tag.Id连接在ImageTagIds.Id上

I added a database diagram in SSMS and created all the keys and relationships. 我在SSMS中添加了一个数据库图,并创建了所有键和关系。

Within VS 2012, I create a new EF (.edmx) file, and add my tables. 在VS 2012中,我创建了一个新的EF(.edmx)文件,并添加了表。 VS does something with witchcraft and I can now treat my tables as objects. VS用巫术做一些事情,现在我可以将桌子当作对象了。 This works great, I can query and save without exceptions. 这很好用,我可以毫无例外地查询和保存。

The issue I have is creating the relationship. 我遇到的问题是建立关系。

This is how far I've got 这就是我走了多远

    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();
    }

The above saves into the Tags table and the Image table but, the ImageTagIds table remains empty. 上面的内容保存到Tags表和Image表中,但是ImageTagIds表保持为空。 I can see why, I never attempt to write to it, but this is where I am lost. 我明白为什么,我从不尝试写信,但这就是我迷路的地方。 I don't know what I can write/code to the ImageTagsId table. 我不知道可以向ImageTagsId表写入/编码什么。

More research led me to http://www.entityframeworktutorial.net/entity-relationships.aspx and this says (I think) EF should know where the relationships are. 更多的研究使我进入了http://www.entityframeworktutorial.net/entity-relationships.aspx ,这(我认为)EF应该知道这些关系在哪里。 Even if it does, I don't know what/how I can save as I will not know what the ID's are going to be when I add new entries into the database. 即使这样做,我也不知道可以保存什么/如何保存,因为当我向数据库中添加新条目时我不知道ID是什么。

You are adding tags and you are adding images but you are not adding tags to images. 您正在添加标签,并且正在添加图像,但没有在图像中添加标签。

Try the following 尝试以下

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

From the perspective of entities this will add a tag to a particular image. 从实体的角度来看,这将为特定图像添加标签。 From the perspective of db tables it will add the tag into the Tags table and ImageTagIds table. 从db表的角度来看,它将标记添加到Tags表和ImageTagIds表中。

EDIT : If you don't have a Tags property you should first ensure your database relations are properly made. 编辑 :如果您没有Tags属性,则应首先确保正确建立数据库关系。 If that is not the case you can try 如果不是这种情况,您可以尝试

TagsImagesIds tagImageRelation = new TagsImagesIds();
tagImageRelation.ImageId = image.Id;
tagImage.Relation.TagId = tag.Id;
_dc.TagsImagesIds.Add(tagImageRelation);

Typically the reason you are missing the Tags property in images is that you have more columns in your table other than TagId and ImageId so EF creates 3 classes to represent your tables instead of 2. 通常,缺少图像中的Tags属性的原因是,表中除了TagId和ImageId之外还有更多列,因此EF创建了3个类来表示表,而不是2。

This is a many to many relationship, implemented with a junction table that has additional properties (and the definition of the key doesn't match with what EF expects for a many-to-many relationship). 这是一个多对多关系,是通过具有附加属性的联结表实现的(并且键的定义与EF对多对多关系的期望不匹配)。 In this case EF treats the junction table as any other entity, so you have to create and save the entries to this table yourself. 在这种情况下,EF将联结表视为其他任何实体,因此您必须自己创建条目并将其保存到该表中。 See note on many-to-may EF relationship at the bottom 请参阅底部有关多对五关系的注释

Provided that your ImagetTagId has the following: ImagetTagId是您的ImagetTagId具有以下内容:

  • a relationship, an navigation property to Image 关系, Image的导航属性
  • a relationship, and navigation property to Tag 关系和Tag导航属性

and the ID is database generated (identity), then you simply have to create all the necessary ImageTagId objects and set the navigation properties. 并且ID是数据库生成的(身份),则只需创建所有必要的ImageTagId对象并设置导航属性。 When you call SaveChanges the DbContext will do the relationship fixup, setting the correct Ids in the ImageTagId objects and saving them to the database. 当您调用SaveChanges ,DbContext将进行关系ImageTagId ,在ImageTagId对象中设置正确的ID并将其保存到数据库。

It should be something like this: 应该是这样的:

    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);
    }

Obviously what you cannot do is to set he Ids in the ImageTagId because they're not available until they are saved. 显然,您无法做的是在ImageTagId设置他ID,因为它们只有在保存后才可用。 That's way it's necessary to have the navigation properties to Tag and Image . 这样一来,就必须具有TagImage的导航属性。

When you call SaveChanges the image is saved to the db, and get its db generated id. 调用SaveChanges ,图像将保存到数据库,并获取其数据库生成的ID。 The same happens when saving each tag. 保存每个标签时也会发生同样的情况。 And, when saving each ImageTagId , as it is related to a tag and an image which already have ids, EF copy those Ids, and save the "fixed-up" object to the DB. 并且,当保存每个ImageTagId ,由于它与已经具有id的标签和图像相关,因此EF复制这些ID,然后将“ fixed-up”对象保存到DB。 Read this on MSDN: Relationships and Navigation Properties , paying gspecial attention to the section Synchronizing the changes between the FKs and Navigation properties . 在MSDN上阅读此文章: 关系和导航属性 ,特别注意同步FK和导航属性之间的更改部分。

Many to many relationships in EF EF中的多对多关系

If you want to define a pure many to many relationship on EF, you need a junction table that only has 如果要在EF上定义纯多对多关系,则需要仅具有

  • an FK to one of the many to many sides 一个FK到多对多边之一
  • an FK to the other side 另一边的FK
  • a PK which is composed of both FKs 由两个FK组成的PK

In your particular case, you should have a table which only has an Id which is a FK to Image, another Id which is an FK to Tag, and a primary key composed of both FKs. 在您的特定情况下,您应该有一个表,该表仅具有一个ID(从FK到图像),另一个ID(从FK到Tag)以及由两个FK组成的主键。

When you use an EF many to many relationship the junction table doesn't appear as an entiy in the model. 当您使用EF多对多关系时,联结表在模型中不会显示为完整。 Instead, you only have a navigation property from each side to a collection on the other side. 相反,您只有从每一侧到另一侧的集合的导航属性。 In your particular side you'd have an Images collection on Tag and a Tags collection on Image. 在您的特定方面,您会在Tag上有一个Images集合,在Image上有一个Tags集合。

If you impelement a many to many like this, the junction table entries will be automatically managed by EF. 如果您像这样实现了很多,则联结表条目将由EF自动管理。

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

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