2009-08-08 40 views
5

我正在写一个LINQ to SQL的基础知识库,我希望允许GetByID和一个int参数。签名是:使用LINQ to SQL确定主键

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

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

+0

对不起,我的答案是没有好 - 我困惑的对象在内存中的列表,并附有表'',其查询数据库。此问题以前在这里回答:http://stackoverflow.com/questions/735140/c-linq-to-sql-refectoring-this-generic-getbyid-method – 2009-08-08 18:39:22

回答

3

就我个人而言,我认为提供采用Func<int,T>选择器参数的SingleOrDefault<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); 
    } 
} 
+0

难道你没有忘记实际检查传入的ID对'c.MyClassID'的值? – GregL 2011-03-22 01:37:12

+0

@GregL - 好。固定。 – tvanfosson 2011-03-22 02:21:18

10

类似下面(支持其他类型的不仅仅是int,但默认为int)。重要的是,不要陷入通过反思来看待Attribute数据的陷阱; LINQ到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); 
} 
+0

这绝对是最好的方法,也是一个很好的答案,因为它指出了LINQ to SQL的一个不太知名的功能(运行时元数据)。 – 2009-08-09 02:31:21