【发布时间】:2019-04-02 19:36:25
【问题描述】:
首先,这是一个简单的示例数据库模型,它已将Products 分配给Categories,其中Products 中的CategoryId 是与Categories 的FK 关系。
产品:
- ProductId (PK),INT
- 产品名称 VARCHAR(255)
- CategoryId (FK),INT
类别
- CategoryId (PK),INT
- 类别名称 VARCHAR(255)
对于 .NET 应用程序数据模型,只有 Product 的非规范化表示被定义为实体类:
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
没有定义Category 类,对于这个例子,没有计划。
在代码优先的实体框架DbContext-派生类中,我设置了DbSet<Product> Products 实体集:
public virtual DbSet<Product> Products { get; set; }
在EntityTypeConfiguration 中,我正在尝试将其连接起来,但我无法使其正常工作:
public class ProductConfiguration : EntityTypeConfiguration<Product>
{
public ProductConfiguration()
{
HasKey(t => t.ProductId);
// How do I instruct EF to pull just the column 'CategoryName'
// from the FK-related Categories table?
}
}
我意识到可以创建一个 SQL 视图,然后我可以告诉 EF 使用 ToTable("App1ProductsView") 映射到该视图,但在本例中,我想避免这样做。
在 SQL ADO.NET ORM 解决方案中,这里没有问题。我可以简单地编写自己的 SQL 语句来执行 INNER JOIN Categories c ON c.CategoryId = p.CategoryId 连接。在填充实体时,如何使用 EF 代码优先 Fluent API 执行相同的内部联接?
在我的研究中,我看到了很多“实体拆分为多个表”的主题,但事实并非如此。类别和产品是两个不同的实体(从数据库的角度来看),但 .NET 代码意味着不知道这一点。
尝试 1 失败:
这不起作用,并产生一个奇怪的查询(通过 SQL Server Profiler 看到)。
流畅的配置:
Map(m =>
{
m.Property(t => t.CategoryName);
m.ToTable("Categories");
});
生成的 SQL:
SELECT
[Extent1].[ProductId] AS [ProductId],
[Extent2].[ProductName] AS [ProductName],
[Extent2].[CategoryId] AS [CategoryId],
[Extent1].[CategoryName] AS [CategoryName],
FROM [dbo].[Categories] AS [Extent1]
INNER JOIN [dbo].[Product1] AS [Extent2] ON [Extent1].[ProductId] = [Extent2].[ProductId]
【问题讨论】:
-
您为什么要这样做?这是一个 ORM,这意味着它需要一个对象来映射。听起来你真的想要更多地控制你的域级别对象,在这种情况下,只需为你的域使用一组单独的对象,为你的数据层使用另一个对象,并使用 automapper 之类的工具
-
你是对的。在这个例子中,域对象被期望更紧密地绑定到 ORM 后端,消除了额外的 ORM-only 实体层和两层之间的后续映射。我很欣赏您对转向真正的 DDD 方法的洞察力。由于当前的设计决定是有争议的,我会离题。我只是希望 EF 专家可以与 EF Fluent API 交谈,以及这是否可能,而无需在 ORM 端创建相当于“特定于域实体的 SQL 视图”。从技术上讲,这似乎是可行的,只是我错过了一些东西......
-
您将其描述为设计是一成不变的。为什么不能简单地映射 Product 和 Category 类并将它们投影到您显示的这个自定义
Product类?
标签: c# .net sql-server entity-framework entity-framework-6