Defining a primary key using LINQ to SQL

I am writing a LINQ to SQL based repository where I want to enable GetByID with an int parameter. Signature:

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

My tables have different names for the primary key. What I would like to do is dynamically determine for each T what is the primary key, and request it for the integer = id value. Any ideas how best to take this off?

+5
c # linq-to-sql
source share
3 answers

Dennis Trollier answered the question about what Ben related in the comments in the question.

+3
source share

Something like below (which supports other types, not just int , but int by default). It is important to note that do not fall into the trap of searching Attribute data through reflection; LINQ-to-SQL also supports objects without attributes:

 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); } 
+10
source share

Personally, I think it would be easier to provide a SingleOrDefault<T> method that takes a Func<int,T> selector argument. You can then provide any desired selector, including one that selects based on this table 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 ); } } 

Using:

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

A strongly typed repository can then use this method to implement GetById ()

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

All Articles