[英]Determine primary key using LINQ to SQL
我正在編寫一個基於LINQ to SQL的存儲庫,我想在其中允許帶有int參數的GetByID。 簽名是:
public T GetByID(int id)
{
// Return
return _dataContext.GetTable<T>() ....;
}
我的表具有不同的主鍵名稱。 我想做的是為每個T動態確定主鍵是什么,並查詢其值為integer = id。 任何想法如何最好地解決這個問題?
類似下面的東西(支持除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);
}
Dennis Troller回答了Ben在問題評論中所提到的問題。
就個人而言,我認為提供一個采用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 );
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.