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

问题描述 投票:0回答:2

我有一个典型的主/详细(用户/设置表)表模式(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();
    }
}
c# entity-framework ef-fluent-api
2个回答
0
投票

实体框架映射到关系数据库,因此必须坚持使用其中的一些概念。这里的主要内容是,每个实体都映射到一个包含该实体的所有记录的表,并且需要一些数据来区分关系。

因此,您需要添加USER_ID以告知哪个记录针对哪个用户(以定义关系)。换句话说,您需要在表格中以及C#实体中使用它。

我认为在代码中首先不可能在实体上没有关系属性。另一方面,您可以创建一些额外的DTO图层来隐藏它。


1
投票

来自EF documentation ......

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

所以,我错了。在我的代码中,UserProfile应该包括UserProfileSetting作为FK(只是ID)或作为独立的对象。

  • 在第一种情况下,应将UserId映射到UserProfileSetting,并将UserProfile中的导航属性更改为... HasMany<UserProfileSetting>(p => p.Settings) .WithOptional() .HasForeignKey(s => s.UserId);
  • 在第二种情况下,(这就是所谓的独立关联)应该在UserProfileSetting中为UserProfile添加一个新的导航属性。
© www.soinside.com 2019 - 2024. All rights reserved.