整体框架核心中的许多关系

时间:2017-04-28 06:41:46

标签: c# entity-framework sqlite uwp

所以,在https://docs.microsoft.com/en-us/ef/core/modeling/relationships?hubRefSrc=email&utm_source=lfemail&utm_medium=email&utm_campaign=lfnotification#lf-content=177107930:682390858中遵循@ zadqvb8的善意建议之后,我仍然无法做到这一点。

是否有人在实体中建立和使用 Many2Many Relationships 在一方的一个实体(A)与另一方的几个不同实体(BCD ...)之间进行实时体验框架核心? (让我们调用结果表" AB")。

框架不支持开箱即用,并且解决方法不会产生在关系中创建的任何实际记录......

背景:标签是一方的实体,而另一方是几个资产类......我只是想为资产添加标签。所描述的解决方案不会在(AB)关系表中生成条目。

使用SQLite,因为这是一个UWP应用程序......请不要讨厌。

- 更新2017-04-29 13:39 CET

非常感谢提供帮助。

为了简单起见,我将发布代码以在ModelImage和ModelTag之间创建一个m2m:

public class ModelImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ModelImageId { get; set; }

    public List<ModelImageTag> Tags { get; set; }
}

public class ModelTag
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ModelTagId { get; set; }

    public List<ModelImageTag> Images { get; set; }
}

public class ModelImageTag
{
   public int ModelImageId { get; set; }
   public ModelImage ModelImage { get; set; }

   public int ModelTagId { get; set; }
   public ModelTag ModelTag { get; set; }
}

这些课程还有更多,但我想这些属性就足够了

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<ModelImageTag>().HasKey(x => new { x.ModelImageId, x.ModelTagId });
    modelBuilder.Entity<ModelImageTag>().HasOne(x => x.ModelImage).WithMany(x => x.Tags).HasForeignKey(x => x.ModelTagId);
    modelBuilder.Entity<ModelImageTag>().HasOne(x => x.ModelTag).WithMany(x => x.Images).HasForeignKey(x => x.ModelImageId);
}

这是添加关系的部分:

ModelImage image = ....;
ModelTag tag = ...;

ModelImageTag iTag = new ModelImageTag { ModelImage = image, ModelTag = tag};
tag.Images.Add(iTag);
image.Tags.Add(iTag);

Context.SaveChanges();

我尝试在ModelImageTag或实体引用中设置ID,没有结果。

我错过了什么?非常感谢任何建议。

2 个答案:

答案 0 :(得分:1)

首先,您为ModelImageTag实体创建的表提供了错误的 ForeignKey 。如您所知,EFCore目前不支持多对多关系。因此,我们使用连接表并映射两个单独的一对多关系。

对于此代码行modelBuilder.Entity<ModelImageTag>().HasOne(x => x.ModelImage).WithMany(x => x.Tags).HasForeignKey(x => x.ModelTagId);,联接表ModelImageTag将与ModelImage创建一对多关系,因此其外键应为ModelImageId,而不是ModelTagId }。更新了模型创建代码,如下所示:

public class MyContext : DbContext
{
   public DbSet<ModelImage> ModelImages { get; set; }
   public DbSet<ModelTag> ModelTags { get; set; }         

   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
       optionsBuilder.UseSqlite("Filename=ModelImageDatabase.db");
   } 
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
       modelBuilder.Entity<ModelImageTag>()
           .HasKey(x => new { x.ModelImageId, x.ModelTagId });
       modelBuilder.Entity<ModelImageTag>()
           .HasOne(x => x.ModelImage)
           .WithMany(x => x.Tags)
           .HasForeignKey(x => x.ModelImageId);
       modelBuilder.Entity<ModelImageTag>()
           .HasOne(x => x.ModelTag)
           .WithMany(x => x.Images)
           .HasForeignKey(x => x.ModelTagId);
   }
}

其次,在将更改保存到数据库之前,您没有代码片段来向数据库添加记录。

image.Tags.Add(iTag);
Context.ModelImages.Add(image);
Context.SaveChanges();

以下是一个完整的示例代码,可以通过联接表ModelImageModelTagModelImageTag之间创建多对多关系,这可能会对您有所帮助。

 var Context = new MyContext();
 ModelImage image = new ModelImage()
 {
     ModelImageId = 101,
     Tags = new List<ModelImageTag>()
 };
 ModelImage image2 = new ModelImage()
 {
     ModelImageId = 102,
     Tags = new List<ModelImageTag>()
 };
 ModelTag tag = new ModelTag()
 {
     ModelTagId = 201,
     Images = new List<ModelImageTag>()
 };
 ModelTag tag2 = new ModelTag()
 {
     ModelTagId = 202,
     Images = new List<ModelImageTag>()
 };
 ModelImageTag iTag = new ModelImageTag { ModelImage = image, ModelTag = tag };
 ModelImageTag iTag2 = new ModelImageTag { ModelImage = image, ModelTag = tag2 };
 ModelImageTag iTag3 = new ModelImageTag { ModelTag = tag, ModelImage = image2 };
 tag.Images.Add(iTag3);
 image.Tags.Add(iTag);
 image.Tags.Add(iTag2);
 Context.ModelImages.Add(image);
 Context.ModelImages.Add(image2);
 Context.ModelTags.Add(tag);
 Context.SaveChanges();

结果:

enter image description here

更多详情请参阅this document。如果您仍有问题,请提供最小的重现项目。

答案 1 :(得分:0)

您的代码:

ModelImage image = ....;
ModelTag tag = ...;

ModelImageTag iTag = new ModelImageTag { ModelImage = image, ModelTag = tag};
tag.Images.Add(iTag);
image.Tags.Add(iTag);

Context.SaveChanges();

更正后的代码:

// in DbContext
DbSet<ModelImage> ModelImages;
DbSet<ModelTags> ModelTags;
DbSet<ModelImageTag> ModelImageTags;

// your code:

ModelImage image = ....;
ModelTag tag = ...;

ModelImageTag iTag = new ModelImageTag { ModelImage = image, ModelTag = tag};
tag.Images.Add(iTag);
image.Tags.Add(iTag);

// tell EF to add the above objects (without this, you got nothing)...
Context.ModelImages.Add(image);  // can also use AddRange()
Context.ModelTags.Add(tag);
Context.ModelImageTags.Add(iTag);

Context.SaveChanges();