如何解决:性能在关系约束的依赖​​和主要角色的数目必须是相同的?如何解决、数目、角色、性能

2023-09-03 12:08:10 作者:花落,淚無聲

我使用实体框架4.3.1对SQL Server 2012数据库,我使用的是POCO的方法。我收到以下错误,我想知道如果任何人都可以解释如何解决它:

ModelValidationException

       

模型生成过程中检测到一个或多个验证错误:     \ tSystem.Data.Entity.Edm.EdmAssociationConstraint::在关系约束的依赖​​和主要角色的属性数必须相同

  

没有的InnerException 可用于任何进一步的信息。

我不能更改数据库模式,这是一个有点古怪,但在这里它是...

**是主键(注意我有​​复合主键) (FK)表示外键

下面是表(如果有帮助,我可以张贴在SQL生成它们,但我不认为这些表是实际问题的例外是在模型的验证):

 一
 - 
** OneId INT NOT NULL
** TwoId INT NOT NULL(FK)
** ThreeId INT NOT NULL(FK)
名称为nvarchar(50)非空

二
 - 
** TwoId INT NOT NULL
** ThreeId INT NOT NULL(FK)
名称为nvarchar(50)非空

三
 - 
** ThreeId NOT NULL
名称为nvarchar(50)非空
 

下面是实体(请注意,我包括在模型中的外键,但高于pretty的标准等):

 公共类三
{
    公众诠释ThreeId {获得;组; }
    公共字符串名称{;组; }
    公共虚拟的ICollection<二>三三两两{获得;私定; }
    公共虚拟的ICollection<一>问鼎{获得;私定; }

    公共无效AddOne(一一)
    {
        如果(一个== NULL)
            抛出新ArgumentNullException(二);

        如果(问鼎== NULL)
            问鼎=新的名单,其中,一>();

        如果(!Ones.Contains(一个))
            Ones.Add(之一);

        one.Three =这一点;
    }

    公共无效AddTwo(二二)
    {
        如果(二== NULL)
            抛出新ArgumentNullException(二);

        如果(三三两两== NULL)
            三三两两=新名单,其中;二>();

        如果(!Twos.Contains(2))
            Twos.Add(二);

        two.Three =这一点;
    }
}

公共类二
{
    公众诠释TwoId {获得;组; }
    公众诠释ThreeId {获得;组; }
    公共字符串名称{;组; }
    公共虚拟三三{获得;组; }
    公共虚拟的ICollection<一>问鼎{获得;私定; }

    公共无效AddOne(一一)
    {
        如果(一个== NULL)
            抛出新ArgumentNullException(二);

        如果(问鼎== NULL)
            问鼎=新的名单,其中,一>();

        如果(!Ones.Contains(一个))
            Ones.Add(之一);

        one.Two =这一点;
    }
}

公共类一
{
    公众诠释OneId {获得;组; }
    公众诠释TwoId {获得;组; }
    公众诠释ThreeId {获得;组; }
    公共虚拟两个二{获得;组; }
    公共虚拟三三{获得;组; }
}
 

这里是数据方面:

 公共类DbCtx:的DbContext
{
    公共DbCtx(字符串的connectionString)
        :基地(的connectionString)
    {
        问鼎=设置<一>();
        三三两两=设置<二>();
        三分球=设置<三>();
    }

    公共DbSet<一>问鼎{获得;私定; }
    公共DbSet<二>三三两两{获得;私定; }
    公共DbSet<三>三分{获得;私定; }

    保护覆盖无效OnModelCreating(DbModelBuilder模型构建器)
    {
        VAR 1 = modelBuilder.Entity<一>();
        one.ToTable(1);

        one.HasKey(D =>新建
                            {
                                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 2 = modelBuilder.Entity<二>();
        two.ToTable(二);

        two.HasKey(D =>新建
                            {
                                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 3 = modelBuilder.Entity<三>();
        three.ToTable(三公);
        three.HasKey(S => s.ThreeId);

        three.Property(P => p.ThreeId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

        base.OnModelCreating(模型构建器);
    }
}
 

最后,这是code片段导致异常:

 使用(VAR CTX =新DbCtx(@......))
{
    Console.WriteLine(ctx.Twos.Count());
}
 

解决方案

究其原因,错误配置不正确,在模型中的关系。这是不正确的:

  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 =>新建{t.TwoId,t.ThreeId});
 

由于相关的FK必须包含主要PK的所有列。此外,还必须从

删除导航属性

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:

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.

There is no InnerException available for any further information.

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

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):

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());
}

解决方案

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 Three to One.