C# 如何在EF中获取实体更改增量?

C# 如何在EF中获取实体更改增量?,c#,.net,entity-framework,sql-server-ce,C#,.net,Entity Framework,Sql Server Ce,我只需要获得更改字段的列表,数据存储是ssce,因此没有可用的触发器 EF中是否支持获取列表或构建通用组件?根据上下文类型和生成的实体,您可以通过几种不同的方式来实现。 对于从实体或POCO继承的对象,您可以使用 对于自跟踪实体,您可以使用实体本身的跟踪器 请提供有关如何生成上下文以及如何进行更改的更多详细信息 编辑(2): 您可以查询ObjectStateManager,查找更改的条目,如下所示: var changed = ctx.ObjectStateManager.GetObjectS

我只需要获得更改字段的列表,数据存储是ssce,因此没有可用的触发器


EF中是否支持获取列表或构建通用组件?

根据上下文类型和生成的实体,您可以通过几种不同的方式来实现。 对于从实体或POCO继承的对象,您可以使用 对于自跟踪实体,您可以使用实体本身的跟踪器

请提供有关如何生成上下文以及如何进行更改的更多详细信息

编辑(2):
您可以查询
ObjectStateManager
,查找更改的条目,如下所示:

 var changed = ctx.ObjectStateManager.GetObjectStateEntries().Where(e=>e.State != EntityState.Unchanged);
编辑(1):

中的以下示例演示如何查询更改:

int orderId = 43680;

using (AdventureWorksEntities context =
new AdventureWorksEntities())
{
var order = (from o in context.SalesOrderHeaders
             where o.SalesOrderID == orderId
             select o).First();

// Get ObjectStateEntry from EntityKey.
ObjectStateEntry stateEntry =
    context.ObjectStateManager
    .GetObjectStateEntry(((IEntityWithKey)order).EntityKey);

//Get the current value of SalesOrderHeader.PurchaseOrderNumber.
CurrentValueRecord rec1 = stateEntry.CurrentValues;
string oldPurchaseOrderNumber =
    (string)rec1.GetValue(rec1.GetOrdinal("PurchaseOrderNumber"));

//Change the value.
order.PurchaseOrderNumber = "12345";
string newPurchaseOrderNumber =
    (string)rec1.GetValue(rec1.GetOrdinal("PurchaseOrderNumber"));

// Get the modified properties.
IEnumerable<string> modifiedFields = stateEntry.GetModifiedProperties();
foreach (string s in modifiedFields)
    Console.WriteLine("Modified field name: {0}\n Old Value: {1}\n New Value: {2}",
        s, oldPurchaseOrderNumber, newPurchaseOrderNumber);

// Get the Entity that is associated with this ObjectStateEntry.
SalesOrderHeader associatedEnity = (SalesOrderHeader)stateEntry.Entity;
Console.WriteLine("Associated Enity's ID: {0}", associatedEnity.SalesOrderID);
}
intorderid=43680;
使用(AdventureWorksEntities)上下文=
新建AdventureWorksEntities())
{
var order=(来自context.SalesOrderHeaders中的o)
其中o.SalesOrderID==orderId
选择o.First();
//从EntityKey获取ObjectStateEntry。
ObjectStateEntry状态项=
context.ObjectStateManager
.GetObjectStateEntry(((IEntityWithKey)order).EntityKey);
//获取SalesOrderHeader.PurchaseOrderNumber的当前值。
CurrentValueRecord rec1=stateEntry.CurrentValues;
字符串oldPurchaseOrderNumber=
(字符串)rec1.GetValue(rec1.GetOrdinal(“PurchaseOrderNumber”);
//更改值。
order.PurchaseOrderNumber=“12345”;
字符串newPurchaseOrderNumber=
(字符串)rec1.GetValue(rec1.GetOrdinal(“PurchaseOrderNumber”);
//获取修改后的属性。
IEnumerable modifiedFields=stateEntry.GetModifiedProperties();
foreach(modifiedFields中的字符串s)
WriteLine(“修改的字段名:{0}\n旧值:{1}\n新值:{2}”,
s、 oldPurchaseOrderNumber、newPurchaseOrderNumber);
//获取与此ObjectStateEntry关联的实体。
SalesOrderHeader associatedEnity=(SalesOrderHeader)stateEntry.Entity;
WriteLine(“关联的Enity的ID:{0}”,associatedEnity.SalesOrderID);
}

使用数据库结构本身通常是一种很好的做法。 这只是你现在的另一种方法

您可以在名为example
ModifiedOn
的表中创建类型为
datetime
的新字段,并在每次更新数据库中的行时对其进行更新

然后,如果要在特定时间后更改行,只需使用:

where ModifiedOn > dateTime

这只是关于如何从不同角度解决问题的另一个建议。

使用向导从db生成模型,典型代码repo.entity.value=newvalue要进行更改,它是否会像“表”那样扩展到多行绑定到一个网格&用户对一行进行更改,但我事先不知道是哪一行!!或者我是否需要为列表中的每条记录获取并存储ObjectStateEntry(可以很容易地拥有>10000个条目)。您可以查询
ObjectStateManager
,仅查看更改。另一个情况是,如果在内存中加载了10k个实体,您可以使用更复杂的方法来加载实体框架,即将实体作为分离的对象加载,在Onchange处理程序附加实体到上下文中,该上下文将在上下文<代码> ObjistStameMeAgAs//Cuth>中创建条目,并且不浪费资源用于整个10K集合的状态条目。还考虑研究可用于实体框架的扩展,例如在其之上建立的存储库,由于默认生成的上下文实现了工作单元模式,并且暗示要一致地使用,所以通常您甚至不需要手动更新字段,该字段有专用的字段类型-时间戳。这种方法完全有道理,但它只允许您获得更改的时间。您仍然需要手动获取实际更改,您可以做的只是将原始记录与新记录一起持久化,或者使用更复杂的方法,如查询日志(在SQL Server中)。另一方面,EntityFramework在执行数据库更新之前已经保存了这些信息,因此使用这些现有数据是非常明显的decision@vittore-是的。我完全同意你的看法。我只是想指出,对于这个特殊的问题,还有其他的方法。