C# Linq-SQL : An UpdateByID method for the Repository Pattern

标签 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?
    }

关于C# Linq-SQL : An UpdateByID method for the Repository Pattern,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/880090/

相关文章:

java - Dozer 中泛型的深度映射

c# - 在 Xamarin Forms 中的 PCL 同步方法中调用异步函数

c# - 构造类型、有界类型和无界类型的含义?

c# - 在此上下文中仅支持原始类型或枚举类型。链接到 SQL

java - 使用 Guice 注入(inject)通用接口(interface)子类型的实现

Java:如何让列表类型接受变量参数

c# - 在asp.net中,我们如何在按钮单击时增加或减少div的大小?

c# - 我可以将匿名类型作为参数传递给函数吗?

用于比较 LINQtoSQL 等值的 C# 表达式

c# - 一对多投影 LINQ 查询重复执行