kmp*_*kmp 31 .net c# entity-framework poco entity-framework-4.3
我正在使用实体框架4.3.1对SQL Server 2012数据库,我正在使用POCO方法.我收到以下错误,我想知道是否有人可以解释如何解决它:
ModelValidationException
在模型生成期间检测到一个或多个验证错误:\ tSystem.Data.Entity.Edm.EdmAssociationConstraint ::关系约束中的从属角色和主要角色中的属性数必须相同.
没有InnerException
任何进一步的信息.
我无法更改数据库架构,这有点奇怪,但这里是......
以下是表格(如果它有助于我发布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
Run Code Online (Sandbox Code Playgroud)
这是实体(注意我在模型中包含外键但不是那个非常标准的):
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; }
}
Run Code Online (Sandbox Code Playgroud)
这是数据上下文:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是导致异常的代码片段:
using (var ctx = new DbCtx(@"....."))
{
Console.WriteLine(ctx.Twos.Count());
}
Run Code Online (Sandbox Code Playgroud)
Lad*_*nka 45
错误的原因是模型中的关系配置不正确.这不正确:
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);
Run Code Online (Sandbox Code Playgroud)
它应该是:
one.HasRequired(t => t.Two)
.WithMany(s => s.Ones)
.HasForeignKey(t => new { t.TwoId, t.ThreeId });
Run Code Online (Sandbox Code Playgroud)
因为依赖的FK必须包含主PK的所有列.您还必须从删除导航属性Three
来One
.