如何解决:性能在关系约束的依赖和主要角色的数量必须相同?(How to fix: The numbe

2019-06-26 16:38发布

我使用实体框架4.3.1对SQL Server 2012数据库,我使用的是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);
    }
}

最后,这是一个代码段,以使异常:

using (var ctx = new DbCtx(@"....."))
{
    Console.WriteLine(ctx.Twos.Count());
}

Answer 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中的所有列。 你还必须删除导航属性从ThreeOne



Answer 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"}))


Answer 3:

这也可以通过造成代码首先从数据库 。

我有,我带来了,根据实体框架公约没有一个显而易见的关键领域的一些看法。 生成的代码把[Key]属性在错误的领域。 事实上,它不能检测到任何独特性,所以它就把[Key]上的所有字段属性。

我能去除所有多余的关键属性,使错误消失。



文章来源: How to fix: The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical?