使用LINQ to SQL确定主键

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

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

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

Dennis Troller回答了Ben在问题评论中所关联的问题。

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

 public static TEntity Get(this DataContext dataContext, int id) where TEntity : class { return Get(dataContext, id); } public static TEntity Get(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>( Expression.Equal( Expression.PropertyOrField(param, idName), Expression.Constant(id, typeof(TKey))), param); return dataContext.GetTable().Single(lambda); } 

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

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

用法:

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

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

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