.net EFCore-将复杂属性字段反规范化到父表中

.net EFCore-将复杂属性字段反规范化到父表中,.net,entity-framework-core,.net,Entity Framework Core,也许这有一个简单的答案,问题是我不知道怎么称呼它 我有一个域模型,类似于: 公共类员工 { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共广播地址{get;set;} } 公营公司 { 公共int Id{get;set;} 公共字符串名称{get;set;} 公共广播地址{get;set;} } 公共课堂演讲 { 公共字符串Street{get;set;} 公共字符串City{get;set;} 公共字符串状态{get;set;} 公共字符串ZipCode{get

也许这有一个简单的答案,问题是我不知道怎么称呼它

我有一个域模型,类似于:

公共类员工
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共广播地址{get;set;}
}
公营公司
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共广播地址{get;set;}
}
公共课堂演讲
{
公共字符串Street{get;set;}
公共字符串City{get;set;}
公共字符串状态{get;set;}
公共字符串ZipCode{get;set;}
}
不要在意实际的领域;重要的是
员工
公司
都有
地址
属性

在数据库中,我不希望有一个规范化的地址表。我当然可以,但我觉得不值得。我想要的是让Address对象的每个字段直接位于所属类型表中;这意味着Employee表和Company表都有一个Street列、一个City列等等

在EF中,我知道如何将地址映射到parents表-类似于:

模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
基于模型创建(modelBuilder);
modelBuilder.Entity().ToTable(“员工”);
// ... 
}

这显然不是我想要的-地址将始终映射到员工,我还需要Company表上的所有it字段。

它被称为Owned Entity Types,甚至文档中也有一个与您的问题几乎相同的示例:

它被称为Owned Entity Types,甚至文档中也有一个与您的问题几乎相同的示例:

尝试使用值转换器。首先用NotMapped属性标记地址类型,这样我们既不必定义主键,也不必定义与其他表的关系

[NotMapped]
public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}
员工和公司类型保持不变

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}
然后,我们可以向OnModelCreating方法添加以下代码来注册值转换器。在数据库中,生成的JSON存储为字符串。无论何时检索一个值,我们都需要将其反序列化为一个地址

modelBuilder.Entity<Employee>()
            .Property(emp => emp.Address)
            .HasConversion(address => JsonSerializer.Serialize(address, null),
               addressFromDb => JsonSerializer.Deserialize<Address>(addressFromDb, null));
modelBuilder.Entity<Company>()
            .Property(comp => comp.Address)
            .HasConversion(address => JsonSerializer.Serialize(address, null),
               addressFromDb => JsonSerializer.Deserialize<Address>(addressFromDb, null));
modelBuilder.Entity()
.Property(emp=>emp.Address)
.HasConversion(地址=>JsonSerializer.Serialize(地址,null),
addressFromDb=>JsonSerializer.Deserialize(addressFromDb,null));
modelBuilder.Entity()
.Property(组件=>组件地址)
.HasConversion(地址=>JsonSerializer.Serialize(地址,null),
addressFromDb=>JsonSerializer.Deserialize(addressFromDb,null));

尝试使用值转换器。首先用NotMapped属性标记地址类型,这样我们既不必定义主键,也不必定义与其他表的关系

[NotMapped]
public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}
员工和公司类型保持不变

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}
然后,我们可以向OnModelCreating方法添加以下代码来注册值转换器。在数据库中,生成的JSON存储为字符串。无论何时检索一个值,我们都需要将其反序列化为一个地址

modelBuilder.Entity<Employee>()
            .Property(emp => emp.Address)
            .HasConversion(address => JsonSerializer.Serialize(address, null),
               addressFromDb => JsonSerializer.Deserialize<Address>(addressFromDb, null));
modelBuilder.Entity<Company>()
            .Property(comp => comp.Address)
            .HasConversion(address => JsonSerializer.Serialize(address, null),
               addressFromDb => JsonSerializer.Deserialize<Address>(addressFromDb, null));
modelBuilder.Entity()
.Property(emp=>emp.Address)
.HasConversion(地址=>JsonSerializer.Serialize(地址,null),
addressFromDb=>JsonSerializer.Deserialize(addressFromDb,null));
modelBuilder.Entity()
.Property(组件=>组件地址)
.HasConversion(地址=>JsonSerializer.Serialize(地址,null),
addressFromDb=>JsonSerializer.Deserialize(addressFromDb,null));

这是一个很好的技巧-我不知道我可以这样设置转换。@BrunoBrant。这里的问题是,您不能在过滤器中使用这些对象的属性。@SvyatoslavDanyliv哦,这当然是有限的。你的答案就是我一直在寻找的答案。“但我还没有掌握EF提供的所有功能,学习像这样的新东西很好。这是一个很好的提示-我不知道我可以设置这样的转换。”BrunoBrant。这里的问题是,您不能在过滤器中使用这些对象的属性。@SvyatoslavDanyliv哦,这当然是有限的。你的答案就是我一直在寻找的答案。但是我还没有掌握EF提供的所有东西,学习像这样的新东西很好。