简体   繁体   English

EF6 插入复合键记录错误

[英]EF6 Inserting Composite key record errors

I have an interesting conundrum occurring that i am hoping others will be able to assist in shedding some light upon.我有一个有趣的难题发生,我希望其他人能够帮助阐明一些问题。

When inserting a new entry using EF6 to a table that has a composite key made up of two Guids where one member is to be assigned from the DB while the other has its value supplied by the application i am getting mixed responses.当使用 EF6 将新条目插入到具有由两个 Guid 组成的复合键的表中时,其中一个成员将从数据库分配,而另一个成员的值由应用程序提供,我得到了混合响应。

For one table the insertion occurs without any issue while for another with the exact same key and identity column setup the insertion fails with a message 'InvalidOperationException: A dependent property in a ReferentialConstraint is mapped to a store-generated column.对于一个表,插入没有任何问题,而对于另一个具有完全相同的键和标识列设置的表,插入失败并显示消息“InvalidOperationException:ReferentialConstraint 中的依赖属性映射到存储生成的列。 Column: 'ID'.'列:'ID'。 Below are the (simplified) classes with their configuration setups以下是(简化的)类及其配置设置

The Class that fails to insert :插入失败的类:

public class User
{
    public Guid ID { get; set; }
    public Guid CompanyId { get; set; }
    public Guid OrganisationId { get; set; }
    public String PasswordHash { get; set; }
    public String Salt { get; set; }
    public String UserName { get; set; }

    public virtual Company Company { get; set; }
    public virtual Organisation Organisation { get; set; }

    // <inconsequential members omitted> 
}


public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        HasKey(u => new { u.CompanyId, u.ID });
        Property(u => u.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        Property(u => u.UserName).IsRequired().HasMaxLength(256);
        Property(u => u.PasswordHash).IsRequired().HasMaxLength(256);
        Property(u => u.Salt).IsRequired().HasMaxLength(256);
        HasRequired(c => c.Company).WithMany(c => c.Users).HasForeignKey(c => c.CompanyId).WillCascadeOnDelete(false);
        HasRequired(c => c.Organization).WithMany(c => c.Users).HasForeignKey(p => p.OrganizationID).WillCascadeOnDelete(false);

        // < inconsequential members omitted>
    }
}

The Class that inserts without issue :没有问题插入的类:

public class AdditionalInformation
{
    public Guid ID { get; set; }
    public Guid CompanyId { get; set; }
    public Guid CustomFieldId { get; set; }
    public Guid UserId{ get; set; }

    public virtual Company Company { get; set; }
    public virtual User User { get; set; }

    // <inconsequential members omitted> 
}

public class AdditionalInformationConfiguration : EntityTypeConfiguration<AdditionalInformation>
{
    public AdditionalInformationConfiguration()
    {
        HasKey(ai => new { ai.CompanyId, ai.ID });
        Property(u => u.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        HasOptional(ai => ai.User).WithMany(u => u.UserAdditionalInformations).HasForeignKey(ai => new { ai.CompanyId, ai.UserID });

        // <inconsequential members omitted> 
    }
}

Simple test i have been using :我一直在使用的简单测试:

using (var context = new DataContext())
{
    var user = context.Users.First(f => f.Company.Subdomain.StartsWith("demo"));
    var customField = context.CustomFields.First(f => f.CompanyId == user.CompanyId);

    context.Users.Add(new User() { CompanyId = user.CompanyId, PasswordHash = "hash", Salt = "salt", UserName = "anew@entry.com" });
    context.AdditionalInformations.Add(new UserAdditionalInformation() { CustomFieldID = customField.ID, CompanyId = user.CompanyId, UserID = user.ID });
    context.SaveChanges();
}

As you can see, both classes have an ID member as well as a CompanyId member.如您所见,这两个类都有一个 ID 成员和一个 CompanyId 成员。 They both have the Key defined as { CompanyId, Id } and the DatabaseGeneratedOption.Identity on the ID member.它们都具有定义为 { CompanyId, Id } 的键和 ID 成员上的 DatabaseGeneratedOption.Identity。

I am very confused as to why when an instance of the AdditionalInformation class is persisted to the DB through the DbContext, the record is created without issue while the User class throws the 'InvalidOperationException: A dependent property in a ReferentialConstraint is mapped to a store-generated column.我很困惑为什么当AdditionalInformation类的实例通过 DbContext 持久化到 DB 时,创建记录没有问题,而User类抛出“InvalidOperationException:ReferentialConstraint 中的依赖属性映射到商店-生成的列。 Column: 'ID'.'列:'ID'。 error.错误。

I have managed to fix my own problem but cannot explain how the fix has had the effect it has.我已经设法解决了我自己的问题,但无法解释修复是如何产生效果的。

The User object had a navigation property to another table which did not expose the FK column on the User object. User 对象具有指向另一个表的导航属性,该属性未公开 User 对象上的 FK 列。 Once the inferred column was exposed, the insertion problem went away.一旦推断出的列暴露出来,插入问题就消失了。

I found this by accident since while trying to understand the problem i noticed that this one FK was not explicitly exposed and so did so, then found that my unit test started working after the change.我偶然发现了这一点,因为在尝试理解问题时,我注意到这个 FK 没有明确公开,所以这样做了,然后发现我的单元测试在更改后开始工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM