2011-01-13 3 views
2

내 도메인 모델에는 모든 클래스가 파생 된 기본 엔터티 클래스가 있습니다.
현재 사용자의 권한을 기반으로 필터를 동적으로 만들 수 있기를 바랍니다.
예 : Employee 클래스의 경우 직원이 자신과 부서를 볼 수 있다고 정의합니다.
어떤 동적 메서드를 호출 할 것인지 동적으로 결정합니다.

public static IQueryable<Employee> CreateLinqFilter(IQueryable<Employee> query, User user) 
    { 
     return query.Where(e => e.Id == user.Id || e.Department.Manager.Id == user.Id); 
    } 

을하고, 내 저장소 기본 클래스에서 동적으로 유형을 결정하고 싶습니다 올바른 CreateLinqFilter 방법 전화 :
내 방법은 다음과 같이 뭔가를 갈 것

protected IQueryable CreateLinq<T>(User user) 
    { 
     var query = Session.Linq<T>(); 
     Type t = typeof(T); 
     //if not an entity- do not perform filter 
     if (!t.IsAssignableFrom(typeof(Entity))) 
     { 
      return query; 
     } 
     //now we know that T is a sub-class of Entity. 
     return CreateLinqFilter<T>(query,user); 
    } 

protected IQueryable CreateLinqFilter<T>(IQueryable<T> query, User user) 
     //the following line won't compile: 
     //where T: Entity 
    { 
     //i'd like to be able to do: 
     //T.CreateFilter(query); 

     //instead, I have to do this? 
     if (typeof(T) == Employee) 
     { 
      return Employee.CreateLinqFilter(query,user); 
     } 
     if (typeof(T) == Department) 
     { 
      return Department.CreateLinqFilter(query,user); 
     } 
     //etc... 
    } 

내가 지금까지 가지고있는 유일한 해결책은 꽤보기 흉한 많은 if-else 블록이다.
누구나 더 좋은 아이디어가 있습니까?
감사
조니

+0

저는 여기에서 뭔가를 놓치고 있습니다 만, Entity 클래스에 "CreateLinqFilter"를 선언 한 다음이 모든 relfection 유형 대신에 선언문을 사용하면 "entity.CreateLinqFilter 내가 말했듯이, 나는 아마도 무언가를 잃어 버렸고, 무엇을 알고 싶습니다. ;-) – Chris

+0

@Chris CreateLinqFilter 함수는 엔티티의 Collections *에서 작동하기 때문에 꽤 귀엽습니다. 무의미한 단일 개체의 맥락에서, 함수는 실제로 정적입니다 ... –

+0

아, 그래, 그 말이 맞아. 난 아직도 제네릭 주위에 머리를 얻는 데 그들이 어디 살 필요가 있습니다. :) – Chris

답변

1

같은 것을보십시오 :

return (IQueryable)typeof(T).GetMethod("CreateLinqFilter").Invoke(null, new object[]{query, user}); 

이 런타임에 방법을 찾기 위해 반사를 사용; 너무 느린 경우 GetMethod의 결과를 어딘가에서 캐싱하는 것이 좋습니다. 이 메서드는 정적 메서드에만 국한되지 않습니다. null을 T 유형의 오브젝트에 대한 포인터로 바꾸십시오. 그리고 이것을 일반 인스턴스 메소드에서도 사용할 수 있습니다.

자세한 내용은 MSDN documentation for the reflection classes; documentation for Invoke에서 좋은 예를 찾을 수 있습니다. # 4.0 C에서

+0

글쎄, 아무도 반사를 좋아해요 ,하지만 그것은 작동하지 않으며, 지금은 최고의 대답 인 것 같습니다. 감사합니다. –

0

, 당신이하지 않으면, 어쩌면 당신은

+0

감사, 몇 가지 시도해 볼게요. 주 .net 4.0으로 업그레이드 할 때 ... –

0

글쎄, 우선,에서는 if..else 블록을 많이 사용하지 않는 첫 번째 대답을 사용할 수 있습니다, 동적 A = T (T)를 사용할 수 있습니다, 스위치를 사용하십시오.

0

정말로 좋은 해결책 인 IMO는 파생 된 저장소 클래스에서 메소드를 호출하는 것이지 기본 저장소에서 호출하지 않습니다. 파생 클래스가 쿼리하는 내용을 알고 있으므로 EmployeesRepository가 명시 적으로 Employee.GetFilter를 호출하므로 아무런 문제가 없습니다.

관련 문제