C# Linq-SQL: An UpdateByID method for the Reposito

2020-06-23 07:51发布

I have implemented a sort of Repository class and it has has GetByID, DeleteByID methods and so on, but I'm having trouble implementing the UpdateByID method.

I did something like this:

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();
    }
}

But it's not updating the passed entity.

Has anyone implemented such a method ?


For reference, here is the GetByID method


[Update]

As Marc correctly suggested, I am merely changing the values of the local variable. So how do you think I should go about this method? Use reflection and copy the properties from entity to item ?

7条回答
对你真心纯属浪费
2楼-- · 2020-06-23 08:41

All you have updated is a local variable; for that to work you would have to copy the member values from entity to item - not quite so simple.


Something like below; the only reason I used TKey was that I tested on Northwind.Customer, which has a string key ;-p

The advantage of using the meta-model is that it works even if you are using POCO classes (and the xml-based mapping), and it doesn't try to update anything unrelated to the model.

For the purposes of the example, I have passed in the data-context, and you need to add a SubmitChanges at some point, but the rest should be directly comparable.

BTW - if you are happy to take the ID from the passed in object, that would be easy too - and then you could support composite identity tables.

    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?
    }
查看更多
登录 后发表回答