所以,在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,没有结果。
我错过了什么?非常感谢任何建议。
答案 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();
以下是一个完整的示例代码,可以通过联接表ModelImage
在ModelTag
和ModelImageTag
之间创建多对多关系,这可能会对您有所帮助。
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();
结果:
更多详情请参阅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();