数据库
首页 > 数据库> > C#Linq-SQL:存储库模式的UpdateByID方法

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

作者:互联网

我已经实现了一种Repository类,它有GetByID,DeleteByID方法等等,但是我在实现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();
    }
}

但它没有更新传递的实体.

有没有人实现过这样的方法?

作为参考,here是GetByID方法

[更新]

正如Marc正确建议的那样,我只是在改变局部变量的值.那你觉得我应该怎么做这个方法呢?使用反射并将属性从实体复制到项目?

解决方法:

您更新的只是一个局部变量;为了实现这一点,你必须将成员值从一个实体复制到一个项目 – 不是那么简单.

像下面的东西;我使用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-to-sql,repository-pattern,generics
来源: https://codeday.me/bug/20190716/1473411.html