Проблема с основными / подробными таблицами и Entity Framework - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть типовая схема таблицы master / detail (таблица User / Settings) (SQL Server) и настройка Entity Framework с использованием Fluent API для работы с этими таблицами.

Я определяю это как независимую связь, поэтомукласс UserProfileSetting не включает в себя свойство UserId, но, как я понимаю, оно правильно отображается в конфигурации.

Что ж, моя проблема в том, что когда один элемент Settings обновляется для профиля,на уровне базы данных настройки обновляются для всех пользователей.В основном USER_ID не учитывается.

Произведенный SQL-запрос выглядит так:

UPDATE [dbo].[T_USERPROFILE_SETTING]
SET [VALUE] = @0
WHERE ([KEY] = @1)

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

Текущий код ниже ...

Код обновления данных

var entry = profile.Settings.Where(s => s.Key == key).SingleOrDefault();

if (entry != null)
{
    entry.Value = value;
} else {
    var setting = /* Here create a new setting */
    profile.Settings.Add(setting);
}

DataContext.SaveChanges();

Объекты:

public partial class UserProfile
{
    [Key]
    public string UserId { get; set; }
    public DateTimeOffset LastLogin { get; set; }
    public ICollection<UserProfileSetting> Settings { get; set; }
}

public class UserProfileSetting
{
    public UserProfileSetting() { }

    public string Key { get; set; }
    public string Value { get; set; }
}

Конфигурация объекта:

public class UserProfileConfiguration : EntityTypeConfiguration<UserProfile>
{
    public UserProfileConfiguration()
    {
        ToTable("T_USERPROFILE");

        HasKey<string>(p => p.UserId);

        Property(p => p.UserId)
            .HasColumnName("USER_ID")
            .HasMaxLength(50)
            .IsUnicode()
            .IsRequired();

        Property(p => p.LastLogin)
            .HasColumnName("LAST_LOGIN_AT")
            .IsRequired();

        HasMany<UserProfileSetting>(p => p.Settings)
            .WithOptional()
            .Map(m => m.MapKey("USER_ID"));
    }
}

public class UserProfileSettingConfiguration : EntityTypeConfiguration<UserProfileSetting>
{
    public UserProfileSettingConfiguration()
    {
        ToTable("T_USERPROFILE_SETTING");

        HasKey(p => p.Key );

        Property(p => p.Key)
            .HasColumnName("KEY")
            .HasMaxLength(50)
            .IsUnicode()
            .IsRequired();

        Property(p => p.Value)
            .HasColumnName("VALUE")
            .IsUnicode()
            .IsRequired();
    }
}

Ответы [ 2 ]

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

Из Документация EF ...

Когда столбцы внешнего ключа не включены в модель, информация об ассоциации управляется как независимый объект.Отношения отслеживаются через ссылки на объекты вместо свойств внешнего ключа.Этот тип ассоциации называется независимой ассоциацией.Наиболее распространенный способ изменения независимой ассоциации - это изменение свойств навигации, которые создаются для каждой сущности, которая участвует в ассоциации.

Итак, я ошибся.В моем коде UserProfile должен включать UserProfileSetting как FK (просто ID) или как независимый объект.

  • В 1-м случае UserId должен быть сопоставлен с UserProfileSetting и свойством навигациив UserProfile должен быть изменен на ...

    HasMany<UserProfileSetting>(p => p.Settings) .WithOptional() .HasForeignKey(s => s.UserId);

  • Во втором случае (это то, что называется Независимая ассоциация ) новое свойство навигации должно быть добавлено в UserProfileSetting для UserProfile.

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

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

Поэтому вам нужно добавить USER_ID, чтобы сказать, какая запись для какойпользователь (для определения отношения).Другими словами, вам нужно иметь его в таблице, а также в сущности C #.

Я не думаю, что сначала в коде возможно не иметь свойства отношения к сущности.С другой стороны, вы можете создать дополнительный слой DTO, чтобы скрыть его.

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