【发布时间】:2020-08-13 08:57:28
【问题描述】:
我正在使用 SQL Server 更改跟踪,并且正在尝试将 Microsoft Docs 中的这篇文章改编为实体框架应用程序:Work with Change Tracking。
我想使用实体框架运行这个 SQL 查询:
SELECT
P.*, CT.*
FROM
dbo.Product AS P
RIGHT OUTER JOIN
CHANGETABLE(CHANGES dbo.Product, @last_synchronization_version) AS CT
ON
P.ProductID = CT.ProductID
这是我目前所得到的:
public class Product
{
public int ProductID { get; set; }
// omitted dozens of other properties
}
public class ProductChange
{
public int ProductID { get; set; }
public Product? Product { get; set; }
public long SYS_CHANGE_VERSION { get; set; }
public long? SYS_CHANGE_CREATION_VERSION { get; set; }
public char SYS_CHANGE_OPERATION { get; set; }
public byte[]? SYS_CHANGE_COLUMNS { get; set; }
public byte[]? SYS_CHANGE_CONTEXT { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ProductChange>()
.HasNoKey()
.ToView(null);
base.OnModelCreating(modelBuilder);
}
long lastSynchronizationVersion = ...; // obtained as described in "Work with Change Tracking"
const string sql = @"
SELECT
P.*, CT.*
FROM
dbo.Product AS P
RIGHT OUTER JOIN
CHANGETABLE(CHANGES dbo.Product, {0}) AS CT
ON
P.ProductID = CT.ProductID";
var changes = await dbContext.Set<ProductChange>.FromSqlRaw(sql, lastSynchronizationVersion);
它不起作用,因为 EF 不了解 P.* 如何映射到 public Product? Product { get; set; }。当我删除 Product 属性并从查询中删除 P.* 时,事情会按预期工作。但是,我需要所有属性,而不仅仅是 ID。
将Product 的所有属性复制到ProductChange 并使其都可以为空,但我真的不想这样做。
在实践中,我将不仅对产品使用更改跟踪,还对具有许多属性的数十种实体类型使用更改跟踪。必须在两个地方指定每个属性只是为了让 Entity Framework 与更改跟踪配合得很好。
有没有办法让无钥匙实体类型做我想做的事?还是我必须使用 ADO.NET 的 ExecuteReader 并手动映射结果?
【问题讨论】:
标签: c# sql-server entity-framework entity-framework-core change-tracking