我们将 Linq2DB ORM 库用于我们的 .NET ORM 模型,请参阅https://github.com/linq2db/linq2db
如何发送仅更改列的更新?现在 SQL 查询包括所有的列和值
我们将 Linq2DB ORM 库用于我们的 .NET ORM 模型,请参阅https://github.com/linq2db/linq2db
如何发送仅更改列的更新?现在 SQL 查询包括所有的列和值
目前没有跟踪对象级别更改的机制以仅更新更改的属性,但是如果您知道哪些列发生了更改,则可以将 set 函数与 update 函数结合使用来进行部分更新(就像给出的示例一样在 github 页面中)
using (var db = new DbNorthwind())
{
db.Product
.Where(p => p.ProductID == product.ProductID)
.Set(p => p.Name, product.Name)
.Set(p => p.UnitPrice, product.UnitPrice)
.Update();
}
首先,linq2db 是一个轻量级的 ORM。什么意味着它没有繁重的上下文,并且它不知道任何有关实体更改的信息,而且永远不会 - 如果您想要更改跟踪而不是使用实体框架或 NHibernate。所以你必须自己实现更改跟踪(如果你真的需要它)或更新整个实体(就像你做的那样)。如果您知道更新的列,则可以使用提供的任何语法(请参阅Linq2Db crud 操作)。如果您只知道更改的列名 - 您可以动态构造 linq 表达式并使用一种语法Linq2Db crud operations。
我对 L2DB 有类似的要求,我最终在下面编写了这段代码。它使用了一个包装类 ( BaseAuditor
),但希望您能明白这一点。有一天,我可能会将此代码移动到某种基础 POCO 类中,我的所有 L2DB 类依次继承自该类,但实际上我不确定性能损失是否值得。无论如何,为了它的价值:
private class Change
{
public MemberExpression Extract = null;
public object Value = null;
}
private List<Change> Changes = new List<Change>();
/// <summary>
/// Records this change, for application later
/// </summary>
/// <typeparam name="TV"></typeparam>
/// <param name="extract"></param>
/// <param name="value"></param>
/// <returns></returns>
public BaseAuditor<T> Set<TV>(Expression<Func<T, TV>> extract, TV value)
{
// Record this change for use later
var memberExpression = (MemberExpression)extract.Body;
this.Changes.Add(new Change() {Extract = memberExpression, Value = value});
return this;
}
/// <summary>
/// Applies our changes to the given entity
/// </summary>
/// <param name="entity"></param>
private void ApplyChanges(T entity)
{
foreach (var change in this.Changes) {
var property = (PropertyInfo)change.Extract.Member;
property.SetValue(entity, change.Value, null);
}
}