有些问题/答案与我要提出的问题类似,但是他们都没有完整答案。 (对不起,如果我在搜索时错过了一些东西)
数据库结构:
public class ApplciationDbContext : DbContext()
{
public DbSet<Photo> Photos { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Tag_Photo_XREF> TagPhoto_XREF { get; set; }
}
public abstract class BaseEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
}
public class Tag : BaseEntity
{
public Tag()
{
Photos = new HashSet<Tag_Photo_XREF>();
}
public string TagText { get; set; }
public virtual ICollection<Tag_Photo_XREF> Photos { get; set; }
}
public class Tag_Photo_XREF : BaseEntity
{
public Guid TagId { get; set; }
public Guid PhotoId { get; set; }
public int Score { get; set; }
public virtual Tag Tag { get; set; }
public virtual Photo Photo { get; set; }
}
public class Photo : BaseEntity
{
public Photo()
{
Tags = new HashSet<Tag_Photo_XREF>();
GeneratedTags = new HashSet<GeneratedTag_Photo_XREF>();
}
public virtual ICollection<Tag_Photo_XREF> Tags { get; set; }
}
}
我看到所有这些都挂在一起,但我的问题是: 1)如何防止标签上的重复插入主要。 2)首先如何插入?我这样做:
Photo p = new Photo();
Tag_Photo_XREF tagPhotoXref1 = new Tag_Photo_XREF();
tagPhotoXref1.Tag = new Tag() { TagText = "...1" };
Tag_Photo_XREF tagPhotoXref2 = new Tag_Photo_XREF();
tagPhotoXref2.Tag = new Tag() { TagText = "...2" };
Tag_Photo_XREF tagPhotoXref3 = new Tag_Photo_XREF();
tagPhotoXref3.Tag = new Tag() { TagText = "...3" };
p.Tags.Add(tagPhotoXref1);
p.Tags.Add(tagPhotoXref2);
p.Tags.Add(tagPhotoXref3);
dbContext.Photos.Add(p);
dbContext.SaveChanges();
或类似的东西:
Photo p = new Photo();
Tag_Photo_XREF tagPhotoXref1 = new Tag_Photo_XREF();
tagPhotoXref1.Tag = new Tag() { TagText = "...1" };
tagPhotoXref1.Photo = p;
Tag_Photo_XREF tagPhotoXref2 = new Tag_Photo_XREF();
tagPhotoXref2.Tag = new Tag() { TagText = "...2" };
tagPhotoXref1.Photo = p;
Tag_Photo_XREF tagPhotoXref3 = new Tag_Photo_XREF();
tagPhotoXref3.Tag = new Tag() { TagText = "...3" };
tagPhotoXref1.Photo = p;
dbContext.TagPhoto_XREF.Add(tagPhotoXref1);
dbContext.TagPhoto_XREF.Add(tagPhotoXref2);
dbContext.TagPhoto_XREF.Add(tagPhotoXref3);
dbContext.Photos.Add(p);
dbContext.SaveChanges();
这两种方式看起来都非常混乱而且过于复杂。如果我不需要链接表上的Score属性,那么这将是非常不同的。
与此相关的另一个问题是,如果我与来自不同用户的ApplicationDbContext有多个连接,那么如何阻止插入相同的标记(文本必须是唯一的)
也许我错过了使其复杂化的重点和方法。
谢谢
史蒂夫
答案 0 :(得分:0)
通常,当您在其他两个表之间有一个外部参照表时,不要使用标识/代理主键。外部参照的主键是两个实体键的复合键:在您的情况下,它将是TagId,PhotoId
现在考虑您正在使用BaseEntity将主键定义为所有实体上的标识,您没有那么奢侈(除非您更改代码)。我能看到的唯一解决方案是在这两列上放置一个唯一索引(您可以使用迁移来实现)。另一个选项只是为了防止在您的应用程序中使用业务逻辑重复。
对于您的其他问题,您通常会执行以下操作:
Photo p = new Photo();
Tag tag1 = new Tag() { ... };
Tag tag2 = new Tag() { ... };
p.Tags.Add(new Tag_Photo_XREF { Tag = tag1 };
p.Tags.Add(new Tag_Photo_XREF { Tag = tag2 };
context.Photos.Add(p);
context.SaveChanges();
您不需要将标记和外部参照直接添加到上下文中,因为它是通过您定义的关系添加的。
您可以通过向Photo类添加辅助方法来使自己更容易:
public class Photo
{
// ...
public void AddTag(Tag tagToAdd)
{
this.Tags.Add(new Tag_Photo_XREF { Tag = tagToAdd });
}
// ...
}
这将为您创建外部参照部分。