c# - C#Linq-SQL:用于存储库模式的UpdateByID方法

原文 标签 c# linq-to-sql generics repository-pattern

我已经实现了一种Repository类,并且具有GetByIDDeleteByID方法等,但是在实现UpdateByID方法时遇到了麻烦。

我做了这样的事情:

public virtual void UpdateByID(int id, T entity)
{
        var dbcontext = DB;
        var item = GetByID(dbcontext, id);
        item = entity; 
        dbcontext.SubmitChanges();
}

protected MusicRepo_DBDataContext DB
{
    get
    {
        return new MusicRepo_DBDataContext();
    }
}


但这不是更新传递的实体。

有人实施过这种方法吗?



作为参考,hereGetByID方法



[更新]

正如Marc正确建议的那样,我只是在更改局部变量的值。那么您如何看待这种方法呢?使用反射并将属性从entity复制到item吗?

最佳答案

您更新的只是一个局部变量。为此,您必须将成员值从entity复制到item-并不是那么简单。



像下面这样:我使用TKey的唯一原因是我在Northwind.Customer上进行了测试,该字符串具有字符串键;-p

使用元模型的优点是,即使您正在使用POCO类(以及基于xml的映射),它也可以工作,并且它不会尝试更新与该模型无关的任何内容。

出于示例的目的,我传入了数据上下文,您需要在某个时候添加SubmitChanges,但其余部分应具有直接的可比性。

顺便说一句-如果您很乐意从传入的对象中获取ID,那也很容易-然后您就可以支持复合标识表。

    static void Update<TEntity>(DataContext dataContext, int id, TEntity obj)
        where TEntity : class
    {
        Update<TEntity, int>(dataContext, id, obj);
    }
    static void Update<TEntity, TKey>(DataContext dataContext, TKey id, TEntity obj)
        where TEntity : class
    {
        // get the row from the database using the meta-model
        MetaType meta = dataContext.Mapping.GetTable(typeof(TEntity)).RowType;
        if(meta.IdentityMembers.Count != 1) throw new InvalidOperationException("Composite identity not supported");
        string idName = meta.IdentityMembers[0].Member.Name;

        var param = Expression.Parameter(typeof(TEntity), "row");
        var lambda = Expression.Lambda<Func<TEntity,bool>>(
            Expression.Equal(
                Expression.PropertyOrField(param, idName),
                Expression.Constant(id, typeof(TKey))), param);

        object dbRow = dataContext.GetTable<TEntity>().Single(lambda);

        foreach (MetaDataMember member in meta.DataMembers)
        {
            // don't copy ID
            if (member.IsPrimaryKey) continue; // removed: || member.IsVersion
            // (perhaps exclude associations and timestamp/rowversion? too)

            // if you get problems, try using StorageAccessor instead -
            // this will typically skip validation, etc
            member.MemberAccessor.SetBoxedValue(
                ref dbRow, member.MemberAccessor.GetBoxedValue(obj));
        }
        // submit changes here?
    }

相关文章:

asp.net-mvc - 无法使用InsertOnSubmit()插入新的Employee实体

java - 绑定(bind)不匹配错误和Java通用方法

c# - C#控制台中的System.InvalidCastException

c# - 如何获取设置为“自动”的Canvas元素的宽度和高度?

c# - XPath normalize-space()不能用作步进函数吗?

c# - 如何取消正在进行的XslTransform.Transform

linq-to-sql - 在Linq中执行条件批量更新到SQL

c# - 将存储过程添加到DBML不会生成* .designer.cs代码

java - <T>(尖括号)在Java中是什么意思?

delphi - Delphi在函数中分配泛型值