EF6 Вставка ошибок записи составного ключа - PullRequest
0 голосов
/ 14 марта 2020

У меня есть интересная загадка, и я надеюсь, что другие смогут помочь пролить немного света.

При вставке новой записи с использованием EF6 в таблицу, в которой составной ключ состоит из двух направляющих, где один член должен быть назначен из БД, а другой имеет свое значение, предоставленное приложением, я получаю смешанную информацию ответы.

Для одной таблицы вставка происходит без каких-либо проблем, в то время как для другой с точно такой же настройкой ключа и идентификатора столбца происходит сбой вставки с сообщением «InvalidOperationException: зависимое свойство в ReferentialConstraint сопоставляется сгенерированным хранилищем столбцом , Колонка: «ID». Ниже приведены (упрощенные) классы с их настройками конфигурации

Класс, который не может быть вставлен:

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>
    }
}

Класс, который вставляет без проблем:

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> 
    }
}

Простой тест, который я использую:

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

Как видите, оба класса имеют члена ID, а также члена CompanyId. У них обоих есть ключ, определенный как {CompanyId, Id} и DatabaseGeneratedOption.Identity на элементе ID.

Я очень озадачен тем, почему, когда экземпляр класса AdditionalInformation сохраняется в БД через DbContext, запись создается без проблем, в то время как класс User генерирует исключение InvalidOperationException: зависимое свойство в ReferentialConstraint отображается в столбец, созданный хранилищем. Колонка: «ID». ошибка.

1 Ответ

0 голосов
/ 17 марта 2020

Мне удалось решить мою собственную проблему, но я не могу объяснить, как это исправление дало эффект.

Объект User имел свойство навигации для другой таблицы, которая не отображала столбец FK объекта User. После того, как предполагаемый столбец был выставлен, проблема вставки исчезла.

Я обнаружил это случайно, так как, пытаясь понять проблему, я заметил, что этот FK не был явно выставлен и поэтому сделал это, затем обнаружил, что мой юнит тест начал работать после смены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...