更新LINQ到SQL-我的态度通过反思.寻求改进提示
本文关键字:提示 LINQ SQL- 我的 态度 更新 | 更新日期: 2023-09-27 17:58:41
很多人无法"自动"更新实体——我的意思是分别重写每个值。
想象一下以下情况:我们有一个WCF服务,客户端通过WCF方式接收Order实体,然后更改一些属性,然后通过WCF将其发回。为了正常更新这样的对象,我们需要手动重写每个属性,我不想为每个类编写单独的代码(例如,在属性更改时重写它)。我尝试过Linq2SQLEntityBase,但不知何故,我无法使其工作,尽管我彻底研究了这个示例。所以我的建议是:
public class Alterator<TEntity,TDataContext>
where TDataContext : DataContext, new()
{
/// <summary>
/// Updates a group of entities, performing an atomic operation for each of them (the lambda is executed for each entity separately).
/// </summary>
/// <param name="newOrModifiedEntity">Any kind of IEnumerable of entities to insert or update.</param>
/// <param name="findOriginalLambda">A lambda expression that should return an original TEntity if the entity is to be updated or null if it is new.</param>
public static void AlterAll(IEnumerable<TEntity> entities, Func<TDataContext,TEntity> findOriginalLambda)
{
foreach (TEntity newEntity in entities) {
//a new DataContext initialization is required for this function to work correctly
using (TDataContext dataContext = new TDataContext())
{
dataContext.DeferredLoadingEnabled = false;
Type entityType = typeof(TEntity);
ITable tab = dataContext.GetTable(entityType);
TEntity originalEntity = findOriginalLambda(dataContext);
//if the lambda returned no matching existing record in database, create a new one. No need to if-check for existence before as long as your lambda is properly built
//(I suggest using SingleOrDefault() or FirstOrDefault() in queries).
if (originalEntity == null)
tab.InsertOnSubmit(newEntity);
else
{
foreach (PropertyInfo p in entityType.GetProperties().Where(k => k.CanWrite))
{
var c = p.GetValue(newEntity, null);
var n = p.GetValue(originalEntity, null);
if (c != null && n != null && !c.Equals(n))
p.SetValue(originalEntity, c, null);
}
dataContext.SubmitChanges();
}
}
}
}
/// <summary>
/// Updates a single entity if the lambda expression returns a valid original entity. Inserts one if lambda returns null.
/// </summary>
/// <param name="newOrModifiedEntity">Entity to update or insert.</param>
/// <param name="findOriginalLambda">A lambda expression that should return an original TEntity if the entity is to be updated or null if it is new.</param>
public static void Alter(TEntity newOrModifiedEntity, Func<TDataContext, TEntity> findOriginalLambda) {
AlterAll(new TEntity[] { newOrModifiedEntity }, findOriginalLambda);
}
}
以及一个更新代码示例。它根据其关键字OrderItemID查找订单。如果返回null,将创建一个新条目。
public void AlterOrderItem(OrderItem o) {
Alterator<OrderItem, JDataContext>.Alter(o, t => t.OrderItems.Where(k => k.OrderItemID == o.OrderItemID).SingleOrDefault());
}
有更好的方法吗?我已经试了一个多星期了。
我建议在西风上查看西风业务框架
或下载
它是一个业务对象包装器,使变得更容易
查看附加实体,从服务返回对象后,当客户端更新并返回对象时,在WCF服务中,您可以简单地将对象附加到数据上下文,然后保存更改。