主/明细表和实体框架存在问题

时间:2018-09-14 08:02:02

标签: c# entity-framework ef-fluent-api

我有一个典型的主/明细(用户/设置表)表架构(SQL Server),并使用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();
    }
}

1 个答案:

答案 0 :(得分:1)

来自EF documentation ...

当模型中不包含外键列时,关联信息将作为独立对象进行管理。通过对象引用而不是外键属性来跟踪关系。这种关联称为独立关联。修改独立关联的最常见方法是修改为参与该关联的每个实体生成的导航属性。

所以,我错了。在我的代码中,UserProfile应该将UserProfileSetting包含为FK(仅ID)或独立的对象。

  • 在第一种情况下,应将UserId映射到UserProfileSetting中,并将UserProfile中的导航属性更改为...

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

  • 在第二种情况下(这就是所谓的独立关联),应在UserProfileSetting中为UserProfile添加新的导航属性。