rya*_*net 5 .net c# sql-server entity-framework entity-framework-6
首先,这是一个简单的示例数据库模型,它已Products分配给Categories,其中CategoryIdin Products是FK关系Categories.
产品:
分类
对于.NET应用程序数据模型,只有a的非规范化表示Product被定义为实体类:
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
没有Category定义类,对于此示例,没有计划任何类.
在代码优先的Entity Framework DbContext-derived类中,我设置了DbSet<Product> Products实体集:
public virtual DbSet<Product> Products { get; set; }
Run Code Online (Sandbox Code Playgroud)
而在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?
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到可以创建一个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");
});
Run Code Online (Sandbox Code Playgroud)
结果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]
Run Code Online (Sandbox Code Playgroud)
小智 4
简短的回答:MS EF6 不是为此而设计的,您无法轻松做到这一点。
EF 希望您的实体有一个键,该键是映射表的一部分。您可以使用拆分,即将一些属性放在 Table1 中,将一些属性放在 Table2 中,但前提是两个表共享相同的主键。这仅适用于 [1] -> [0..1] 关系。你所拥有的是一对多。
EF 映射数据库模式的方法是创建两个实体并以Product.Category.Name.
如果您完全不想公开Category实体,您可以使用内部类和 protected 属性,将类别名称公开为sql-ignored property public string CategoryName => this.Category?.Name。
另一种选择是使用未跟踪的 SqlQuery。然后您必须自己编写 SQL 查询,就像您对纯 ADO.NET 解决方案所做的那样。
如果您不想使用 EF 更改跟踪、关系等,请考虑使用更轻的 ORM,例如 Dapper、linq2db 或 BLToolkit。
| 归档时间: |
|
| 查看次数: |
332 次 |
| 最近记录: |