C# 如何解决:关系约束中的从属角色和主要角色中的属性数量必须相同?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11754842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to fix: The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical?
提问by kmp
I am using Entity Framework 4.3.1 against a SQL Server 2012 database and I am using the POCO approach. I am getting the following error and I am wondering if anyone can explain how to fix it:
我正在对 SQL Server 2012 数据库使用 Entity Framework 4.3.1,并且我正在使用 POCO 方法。我收到以下错误,我想知道是否有人可以解释如何解决它:
ModelValidationException
模型验证异常
One or more validation errors were detected during model generation: \tSystem.Data.Entity.Edm.EdmAssociationConstraint: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical.
在模型生成过程中检测到一个或多个验证错误:\tSystem.Data.Entity.Edm.EdmAssociationConstraint:::关系约束中的从属角色和主体角色中的属性数量必须相同。
There is no InnerExceptionavailable for any further information.
没有InnerException任何进一步的信息可用。
I cannot change the database schema and it is a little odd, but here it is...
我无法更改数据库架构,这有点奇怪,但这里是...
- ** are the primary key (notice I have composite primary keys)
- (FK) Denotes a foreign key
- ** 是主键(注意我有复合主键)
- (FK) 表示外键
Here are the tables (if it helps I can post the SQL to generate them but I do not think the tables are actually the problem as the exception is in the validation of the model):
这是表(如果有帮助,我可以发布 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
Here are the entities (notice that I am including the foreign keys in the model but other than that pretty standard):
以下是实体(请注意,我在模型中包含了外键,但不是非常标准的):
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; }
}
And here is the data context:
这是数据上下文:
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);
}
}
Finally, this is a snippet of code to cause the exception:
最后,这是导致异常的代码片段:
using (var ctx = new DbCtx(@"....."))
{
Console.WriteLine(ctx.Twos.Count());
}
采纳答案by Ladislav Mrnka
The reason for the error are incorrectly configured relations in your model. This is not correct:
错误的原因是模型中的关系配置不正确。这是不正确的:
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);
It should be:
它应该是:
one.HasRequired(t => t.Two)
.WithMany(s => s.Ones)
.HasForeignKey(t => new { t.TwoId, t.ThreeId });
Because dependent's FK must contain all columns of principal PK. You must also remove navigation property from Threeto One.
因为家属的 FK 必须包含主体 PK 的所有列。您还必须从Threeto 中删除导航属性One。
回答by OzBob
Note for EF5+: .HasForeignKey has been deprecated from EF 5: List of available methods (https://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.configuration.manytomanyassociationmappingconfiguration_methods(v=vs.103).aspx) - MapLeftKey - MapRightKey - ToTable
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
If one were to need Many to Many where one 'Many' is to an Entity with a CompositeKey is:
如果一个人需要多对多,其中“多”对具有 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"}))
回答by Jess
This can also be caused by Code first from Database.
I had several views that I brought in that did not have an obvious key field according to Entity Framework conventions. The code generated put the [Key]attribute on the wrong field. In fact, it could not detect any uniqueness, so it put the [Key]attribute on all the fields.
根据实体框架约定,我引入了几个没有明显关键字段的视图。生成的代码将[Key]属性放在错误的字段上。实际上,它无法检测到任何唯一性,因此将[Key]属性放在所有字段上。
I was able to remove all of the extra Key attributes to make the error go away.
我能够删除所有额外的 Key 属性以使错误消失。

