使用LINQ to SQL确定主键

时间:2009-08-08 18:09:16

标签: c# linq-to-sql

我正在编写基于LINQ to SQL的存储库,我想在其中允许带有int参数的GetByID。签名是:

public T GetByID(int id)
{
     // Return
     return _dataContext.GetTable<T>() ....;
}

我的表具有不同的主键名称。我想做的是为每个T动态确定主键是什么,并查询其值为integer = id。任何想法如何最好地解决这个问题?

3 个答案:

答案 0 :(得分:10)

下面的内容(支持除int以外的其他类型,但默认为int)。重要的是,不要陷入通过反思查看Attribute数据的陷阱; LINQ-to-SQL也支持没有属性的对象:

public static TEntity Get<TEntity>(this DataContext dataContext, int id)
        where TEntity : class
{
    return Get<TEntity, int>(dataContext, id);
}
public static TEntity Get<TEntity, TKey>(this DataContext dataContext, TKey id)
    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);

    return dataContext.GetTable<TEntity>().Single(lambda);
}

答案 1 :(得分:3)

Dennis Troller answered这是Ben在问题评论中所关联的问题。

答案 2 :(得分:3)

就个人而言,我认为提供一个SingleOrDefault<T>选择器参数的Func<int,T>方法会更容易。然后你可以提供你想要的任何选择器,包括根据该表的id选择的选择器。

 public abstract class Repository<T> where T : class
 {
     public abstract T GetById( int id );
     public T SingleOrDefault( Func<int,T> selector )
     {
           return _dataContext.GetTable<T>().SingleOrDefault( selector );
     }
 }

用法:

 var myObj = repos.SingleOrDefault<MyClass>( c => c.MyClassID == id );

然后,强类型存储库可以使用此方法来实现GetById()

 public class MyClassRepository : Repository<MyClass>
 {
     public override MyClass GetById( int id )
     {
         return this.SingleOrDefault( c => c.MyClassID == id );
     }
 }