Действительные проблемы заказа при сохранении - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть эта ошибка:

UpdateException: невозможно определить действительный порядок для зависимых операций. Зависимости могут существовать из-за ограничений внешнего ключа, требований модели или сгенерированных в хранилище значений.

Когда я создаю записи в базе данных.

База данных (которую нельзя изменить) имеет следующую структуру:

Users
 - UserID (PK, FK, int not null) (no identity spec)

Persons
 - PersonID (PK, Identity spec)

Это мой код:

var user = new User();
user.Username = emailAddresses.First();
user.Password = encryptedPassword;
user.Salt = salt;
user.Active = true;
user.EditedBy = 1;

var role = new User_Roles();
role.UserId = user.UserId;
role.EditedBy = 1;
role.RoleId = 11;

var person = new Person(); 
user.UserId = person.PersonId;

person.FirstName = firstname;
person.LastName = lastname;
person.MiddleName = middleName;

user.Persons.Add(person);
context.Persons.Add(person);
context.Users.Add(user);
context.User_Roles.Add(role);
context.SaveChanges();

Я использую EF 6.2 и не совсем уверен, как заставить это работать. Я использовал подход EDMX для создания модели из БД.

Стоит отметить, что это работает нормально с использованием EF Core, но я не могу использовать EF Core для этой конкретной области проекта.

Есть идеи, что здесь делать? Как я могу заставить пользователя и человека сохранить без ошибок? Я подозреваю, что пользователь в некоторой степени ссылается на саму себя.

Для модели персонажа я добавил следующие атрибуты:

[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }

А для модели User я добавил следующее:

[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public int UserId { get; set; }

Но безрезультатно.

1 Ответ

0 голосов
/ 04 сентября 2018

Проблема, скорее всего, будет:

var person = new Person (); user.UserId = person.PersonId;

Person - это спецификация Identity, у EF здесь не будет идентификатора, пока вы не вызовете SaveChanges.

Лучший способ решить эту проблему - установить отношения сущностей так, чтобы EF связывал отношение 1: 1 между пользователем и персоной в связанном идентификаторе. Я не рекомендую сопоставлять «UserID» с «PersonID», так как это довольно запутанно с точки зрения запроса данных. Просто дайте пользователю PersonId.

Для сопоставления вы можете использовать EntityTypeConfiguration или сопоставить его с modelBuilder.

например.

public class PersonConfiguration : EntityTypeConfiguration<Person>
{
    public PersonConfiguration()
    {
        ToTable("Persons");
        HasKey(x => x.PersonId)
            .Property( x=> x.PersonId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        HasOne(x => x.User)
            .WithRequiredDependency()
            .HasForeignKey(x => x.PersonId);
    }
}

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public PersonConfiguration()
    {
        ToTable("Users");
        HasKey(x => x.PersonId);
    }
}

Затем, когда вы идете, чтобы вставить пользователя / человека:

var person = new Person 
{
    // populate Person details...
    User = new User
    {
        // populate user details... Don't worry about PersonId...
    }
}
dbContext.Persons.Add(person);
dbContext.SaveChanges();

Роли пользователей будут следовать сопоставлению «многие ко многим» между пользователями и ролями. В зависимости от схемы это может быть сделано с или без связывающей сущности (UserRole), хотя обычно проще использовать связывающую сущность, поэтому я рекомендую прочитать, как они отображаются. Для таких вещей, как отслеживание изменений (CreatedAt / CreatedBy и т. Д.), Вам понадобится связать сущности, так как объединения без объединения «многие ко многим» поддерживают только таблицы только с 2x FK, без других столбцов.

...