如何解决:关系约束中的从属角色和主要角色中的属性数量必须相同?
Posted
技术标签:
【中文标题】如何解决:关系约束中的从属角色和主要角色中的属性数量必须相同?【英文标题】:How to fix: The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical? 【发布时间】:2012-07-30 02:08:22 【问题描述】:我正在针对 SQL Server 2012 数据库使用 Entity Framework 4.3.1,并且我正在使用 POCO 方法。我收到以下错误,我想知道是否有人可以解释如何解决它:
ModelValidationException
在模型生成过程中检测到一个或多个验证错误: \tSystem.Data.Entity.Edm.EdmAssociationConstraint: : 关系约束中的从属角色和主体角色中的属性数量必须相同。
没有InnerException
提供更多信息。
我无法更改数据库架构,这有点奇怪,但在这里...
** 是主键(注意我有复合主键) (FK) 表示外键这是表格(如果有帮助,我可以发布 SQL 来生成它们,但我不认为表格实际上是问题,因为例外是在模型验证中):
One
-
**OneId int not null
**TwoId int not null (FK)
**ThreeId int not null (FK)
Name nvarchar(50) not null
Two
-
**TwoId int not null
**ThreeId int not null (FK)
Name nvarchar(50) not null
Three
-
**ThreeId not null
Name nvarchar(50) not null
这里是实体(请注意,我在模型中包含了外键,但不是那个漂亮的标准):
public class Three
public int ThreeId get; set;
public string Name get; set;
public virtual ICollection<Two> Twos get; private set;
public virtual ICollection<One> Ones get; private set;
public void AddOne(One one)
if (one == null)
throw new ArgumentNullException("two");
if (Ones == null)
Ones = new List<One>();
if (!Ones.Contains(one))
Ones.Add(one);
one.Three = this;
public void AddTwo(Two two)
if (two == null)
throw new ArgumentNullException("two");
if (Twos == null)
Twos = new List<Two>();
if (!Twos.Contains(two))
Twos.Add(two);
two.Three = this;
public class Two
public int TwoId get; set;
public int ThreeId get; set;
public string Name get; set;
public virtual Three Three get; set;
public virtual ICollection<One> Ones get; private set;
public void AddOne(One one)
if (one == null)
throw new ArgumentNullException("two");
if (Ones == null)
Ones = new List<One>();
if (!Ones.Contains(one))
Ones.Add(one);
one.Two = this;
public class One
public int OneId get; set;
public int TwoId get; set;
public int ThreeId get; set;
public virtual Two Two get; set;
public virtual Three Three get; set;
这里是数据上下文:
public class DbCtx : DbContext
public DbCtx(string connectionString)
: base(connectionString)
Ones = Set<One>();
Twos = Set<Two>();
Threes = Set<Three>();
public DbSet<One> Ones get; private set;
public DbSet<Two> Twos get; private set;
public DbSet<Three> Threes get; private set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
var one = modelBuilder.Entity<One>();
one.ToTable("One");
one.HasKey(d => new
d.OneId,
d.TwoId,
d.ThreeId
);
one.Property(d => d.OneId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
one.HasRequired(t => t.Two)
.WithMany(s => s.Ones)
.HasForeignKey(t => t.TwoId);
one.HasRequired(t => t.Three)
.WithMany(s => s.Ones)
.HasForeignKey(t => t.ThreeId);
var two = modelBuilder.Entity<Two>();
two.ToTable("Two");
two.HasKey(d => new
d.TwoId,
d.ThreeId
);
two.Property(p => p.TwoId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
two.HasRequired(t => t.Three)
.WithMany(s => s.Twos)
.HasForeignKey(t => t.ThreeId);
var three = modelBuilder.Entity<Three>();
three.ToTable("Three");
three.HasKey(s => s.ThreeId);
three.Property(p => p.ThreeId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
base.OnModelCreating(modelBuilder);
最后,这是一段导致异常的sn-p代码:
using (var ctx = new DbCtx(@"....."))
Console.WriteLine(ctx.Twos.Count());
【问题讨论】:
【参考方案1】:错误的原因是模型中的关系配置不正确。这是不正确的:
one.HasRequired(t => t.Two)
.WithMany(s => s.Ones)
.HasForeignKey(t => t.TwoId);
one.HasRequired(t => t.Three)
.WithMany(s => s.Ones)
.HasForeignKey(t => t.ThreeId);
应该是:
one.HasRequired(t => t.Two)
.WithMany(s => s.Ones)
.HasForeignKey(t => new t.TwoId, t.ThreeId );
因为从属的 FK 必须包含主体 PK 的所有列。您还必须将导航属性从 Three
删除到 One
。
【讨论】:
太好了,谢谢 - 我已经为此苦苦挣扎了一段时间!【参考方案2】:EF5+ 的注意事项: .HasForeignKey 已从 EF 5 中弃用:可用方法列表 (https://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.configuration.manytomanyassociationmappingconfiguration_methods(v=vs.103).aspx) - MapLeftKey - MapRightKey - ToTable
如果需要多对多,其中一个“多”对于具有 CompositeKey 的实体是:
one.HasKey(t => new t.TwoId, t.ThreeId );
one.HasRequired(t => t.Two)
.WithMany(s => s.Ones)
.Map(m=>m.MapLeftKey("OneId").MapRIghtKey(new string[]"TwoId", "ThreeId"))
【讨论】:
【参考方案3】:这也可能是由Code first from Database 引起的。
根据实体框架约定,我引入了几个没有明显关键字段的视图。生成的代码将[Key]
属性放在错误的字段上。事实上,它无法检测到任何唯一性,因此它在所有字段上都添加了[Key]
属性。
我能够删除所有额外的 Key 属性以使错误消失。
【讨论】:
在我的例子中,我添加了一个ForeignKey
引用,它与 EF 在视图上创建的无效 Composite Key
冲突。以上是关于如何解决:关系约束中的从属角色和主要角色中的属性数量必须相同?的主要内容,如果未能解决你的问题,请参考以下文章
在 SleekXMPP 中接收带有消息的“角色”和/或“从属关系”
Missed User 属性,用于计算 asp.net 核心身份中的用户/角色数
数字人C4D角色动画研究之一:约束Constraint -1
学校(School)主要有3大角色:学校(School),讲师(Teacher),学员(Student)。请用Python语言简要实现这些类及及其属性,以及它们之间的关系。