3 方式多对多流利 api
3 way many to many with fluent api
我想使用代码优先和流畅的方式创建具有 3 种关系的数据库表 api。
在我设计的例子中,一个团队应该有一只猫、一只狗和一只猪的独特组合。另一个团队可能包含相同的 Cat 和 Pig,但不是相同的 Dog 等等。
首先,我希望能够获得包含特定动物的团队。 myCat.Teams()
如果可能的话,我也想强制执行唯一性。
public class Cat
{
public int Id { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Dog
{
public int Id { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Pig
{
public Guid { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Team
{
public int Id { get; set; }
public int CatId { get; set; }
public int DogId { get; set; }
public Guid PigId { get; set; }
public virtual Cat Cat {get; set;}
public virtual Dog Dog {get; set;}
public virtual Pig Pig {get; set;}
}
在 OnModelCreating() 中,为这些对象(CatMap、DogMap、PigMap、TeamMap)添加了 EntityTypeConfigurations。
我已经尝试从 TeamMap class 或从另一个方向设置 HasMany 关系。例如,在 DogMap 中:
HasMany(t => t.Teams)
.WithRequired(t => t.Dog)
.HasForeignKey(t => t.DogId);
但是每当我尝试添加迁移时,我都会收到如下错误:
tSystem.Data.Entity.Edm.EdmAssociationConstraint: : 关系约束中从属角色和主要角色中的属性数必须相同。
如何正确设置这些关联以实现上述两个目标?谢谢!!
团队 class 不应有自己的 ID,因为主键是 Cat、Dog、Pig 的组合。所以,它应该是这样的:
public class Team
{
public int CatId { get; set; }
public int DogId { get; set; }
public Guid PigId { get; set; }
public virtual Cat Cat { get; set; }
public virtual Dog Dog { get; set; }
public virtual Pig Pig { get; set; }
}
映射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//primary key, composed by a combination
modelBuilder.Entity<Team>()
.HasKey(i => new { i.CatId, i.DogId, i.PigId });
modelBuilder.Entity<Team>()
.HasRequired(i => i.Cat)
.WithMany(i => i.Teams)
.HasForeignKey(i => i.CatId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Team>()
.HasRequired(i => i.Dog)
.WithMany(i => i.Teams)
.HasForeignKey(i => i.DogId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Team>()
.HasRequired(i => i.Pig)
.WithMany(i => i.Teams)
.HasForeignKey(i => i.PigId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
生成的迁移:
CreateTable(
"dbo.Teams",
c => new
{
CatId = c.Int(nullable: false),
DogId = c.Int(nullable: false),
PigId = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.CatId, t.DogId, t.PigId })
.ForeignKey("dbo.Cats", t => t.CatId, cascadeDelete: true)
.ForeignKey("dbo.Dogs", t => t.DogId, cascadeDelete: true)
.ForeignKey("dbo.Pigs", t => t.PigId, cascadeDelete: true)
.Index(t => t.CatId)
.Index(t => t.DogId)
.Index(t => t.PigId);
CreateTable(
"dbo.Cats",
c => new
{
Id = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Dogs",
c => new
{
Id = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Pigs",
c => new
{
PigId = c.Guid(nullable: false),
})
.PrimaryKey(t => t.PigId);
如果因为某些原因Team必须有自己的Id;更改模型如下:
public class Team
{
public int TeamId { get; set; }
//....
}
映射:
modelBuilder.Entity<Team>()
.HasKey(i => i.TeamId);
//if you want to make the teamId an auto-generated column
modelBuilder.Entity<Team>()
.Property(i => i.TeamId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
//if you want to make the cat, dog, and pig combination unique
modelBuilder.Entity<Team>()
.Property(i => i.CatId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_TeamComp", 1) { IsUnique = true }));
modelBuilder.Entity<Team>()
.Property(i => i.DogId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_TeamComp",2) { IsUnique = true }));
modelBuilder.Entity<Team>()
.Property(i => i.PigId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_TeamComp", 3) { IsUnique = true }));
我想使用代码优先和流畅的方式创建具有 3 种关系的数据库表 api。
在我设计的例子中,一个团队应该有一只猫、一只狗和一只猪的独特组合。另一个团队可能包含相同的 Cat 和 Pig,但不是相同的 Dog 等等。
首先,我希望能够获得包含特定动物的团队。 myCat.Teams()
如果可能的话,我也想强制执行唯一性。
public class Cat
{
public int Id { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Dog
{
public int Id { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Pig
{
public Guid { get; set; }
public virtual ICollection<Team> Teams { get; set; }
}
public class Team
{
public int Id { get; set; }
public int CatId { get; set; }
public int DogId { get; set; }
public Guid PigId { get; set; }
public virtual Cat Cat {get; set;}
public virtual Dog Dog {get; set;}
public virtual Pig Pig {get; set;}
}
在 OnModelCreating() 中,为这些对象(CatMap、DogMap、PigMap、TeamMap)添加了 EntityTypeConfigurations。
我已经尝试从 TeamMap class 或从另一个方向设置 HasMany 关系。例如,在 DogMap 中:
HasMany(t => t.Teams)
.WithRequired(t => t.Dog)
.HasForeignKey(t => t.DogId);
但是每当我尝试添加迁移时,我都会收到如下错误:
tSystem.Data.Entity.Edm.EdmAssociationConstraint: : 关系约束中从属角色和主要角色中的属性数必须相同。
如何正确设置这些关联以实现上述两个目标?谢谢!!
团队 class 不应有自己的 ID,因为主键是 Cat、Dog、Pig 的组合。所以,它应该是这样的:
public class Team
{
public int CatId { get; set; }
public int DogId { get; set; }
public Guid PigId { get; set; }
public virtual Cat Cat { get; set; }
public virtual Dog Dog { get; set; }
public virtual Pig Pig { get; set; }
}
映射:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//primary key, composed by a combination
modelBuilder.Entity<Team>()
.HasKey(i => new { i.CatId, i.DogId, i.PigId });
modelBuilder.Entity<Team>()
.HasRequired(i => i.Cat)
.WithMany(i => i.Teams)
.HasForeignKey(i => i.CatId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Team>()
.HasRequired(i => i.Dog)
.WithMany(i => i.Teams)
.HasForeignKey(i => i.DogId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Team>()
.HasRequired(i => i.Pig)
.WithMany(i => i.Teams)
.HasForeignKey(i => i.PigId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
生成的迁移:
CreateTable(
"dbo.Teams",
c => new
{
CatId = c.Int(nullable: false),
DogId = c.Int(nullable: false),
PigId = c.Guid(nullable: false),
})
.PrimaryKey(t => new { t.CatId, t.DogId, t.PigId })
.ForeignKey("dbo.Cats", t => t.CatId, cascadeDelete: true)
.ForeignKey("dbo.Dogs", t => t.DogId, cascadeDelete: true)
.ForeignKey("dbo.Pigs", t => t.PigId, cascadeDelete: true)
.Index(t => t.CatId)
.Index(t => t.DogId)
.Index(t => t.PigId);
CreateTable(
"dbo.Cats",
c => new
{
Id = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Dogs",
c => new
{
Id = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Pigs",
c => new
{
PigId = c.Guid(nullable: false),
})
.PrimaryKey(t => t.PigId);
如果因为某些原因Team必须有自己的Id;更改模型如下:
public class Team
{
public int TeamId { get; set; }
//....
}
映射:
modelBuilder.Entity<Team>()
.HasKey(i => i.TeamId);
//if you want to make the teamId an auto-generated column
modelBuilder.Entity<Team>()
.Property(i => i.TeamId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
//if you want to make the cat, dog, and pig combination unique
modelBuilder.Entity<Team>()
.Property(i => i.CatId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_TeamComp", 1) { IsUnique = true }));
modelBuilder.Entity<Team>()
.Property(i => i.DogId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_TeamComp",2) { IsUnique = true }));
modelBuilder.Entity<Team>()
.Property(i => i.PigId)
.HasColumnAnnotation(IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_TeamComp", 3) { IsUnique = true }));