首页 > 解决方案 > EF Core 复合类到同一张表中

问题描述

我一直在到处搜索并阅读文档,但似乎找不到与我类似的场景。

情况如下。在 C# 中,我有 3 个类:

[Table("my_baseline_table")]
class Baseline
{
   public Guid Id { get; set; }
   public ClassA ClassA { get; set; }
   public ClassB ClassB { get; set; }
}

class ClassA
{
   public string Property1 { get; set; }
   public string Property2 { get; set; }
   public string Property3 { get; set; }
}

class ClassB
{
   public string Property4 { get; set; }
   public string Property5 { get; set; }
   public string Property6 { get; set; }
}

我的类“ClassA”和“ClassB”实际上有更多的属性,每个大约 12 个,只是为了保持简单。

然后在 SQL 上,我有一个包含所有列的表:

dbo.my_baseline_table
   id
   property1
   property2
   property3
   property4
   property5
   property6

现在我不知道如何告诉 EF 这种关系。因此,它开始抱怨“A 类”需要有一个 id 等等。

我将这些属性分为 2 个类的原因是因为它可以让我更轻松地基于它创建一些 JSON 文件,而无需单独选择每个属性。

任何人都知道如何实现这一目标或其他建议来完成这项工作?

谢谢你。

标签: entity-framework.net-core

解决方案


实体应反映表结构。生成 Json 是一个单独的问题,我建议声明一个适合该目的的 DTO 结构,并将您的实体投影到可以序列化为 JSON 的 DTO 结构中。Automapper 非常适合此类操作,并提供了ProjectTo一种集成到 EF 的 Linq 实现中以生成查询的方法。

// Entity
public class Baseline
{
   public Guid Id { get; set; }
   public string Property1 { get; set; }
   // et. al.
}

// DTOs
[Serializable]
public class BaselineDTO
{ 
    public Guid Id { get; set; }
    public ClassADTO ClassA { get; set; }
    public ClassBDTO ClassB { get; set; }
}

[Serializable]
class ClassADTO
{
   public string Property1 { get; set; }
   public string Property2 { get; set; }
   public string Property3 { get; set; }
}

[Serializable]
class ClassBDTO
{
   public string Property4 { get; set; }
   public string Property5 { get; set; }
   public string Property6 { get; set; }
}

然后,当您读取数据以序列化为 JSON 时:

var config = new MapperConfiguration(cfg => 
{
    cfg.CreateMap<Baseline, BaselineDTO>()
       .ForMember(dest => dest.ClassA, opt => opt.MapFrom(src => src))
       .ForMember(dest => dest.ClassB, opt => opt.MapFrom(src => src));
    cfg.CreateMap<BaseLine, ClassADTO>();
    cfg.CreateMap<BaseLine, ClassBDTO>();
});

var baselines = context.Baselines
    .Where(/* conditions */)
    .ProjectTo<BaselineDTO>(config)
    .ToList();

这将为您提供序列化为 JSON 的所需结构。将同一源(实体)映射到三个 DTO 看起来有点奇怪,但前提是实体和 DTO 之间的属性名称是一致的,Automapper 将计算出要复制的值。


推荐阅读