2009-08-08 6 views
5

int 매개 변수와 함께 GetByID를 허용하려는 LINQ to SQL 기반 리포지토리를 작성하고 있습니다. 서명은 다음과 같습니다.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 –

답변

3

개인적으로는 선택기 인수를 사용하는 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); 

강력한 형식의 respository 다음() 단지 int 이외의 다른 유형을 지원 아래 같은

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

실제로 전달 된 것을 확인하는 것을 잊지 않았습니까? id 'c.MyClassID'에 대한 값? – GregL

+0

@ GregL - 잘 잡습니다. 결정된. – tvanfosson

10

뭔가를 (GetById을 구현하기 위해이 방법을 사용할 수 있습니다, 기본값은 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의 덜 잘 알려진 기능 (런타임 메타 데이터)을 지적하므로이 방법이 가장 좋은 접근 방법이며 좋은 대답입니다. –

관련 문제