2010-06-03 3 views
0

내가 포항 강판의 집합을 가지고 모두 다음과 같은 간단한 인터페이스 구현 :EF/LINQ :() 하위 유형의 속성에 대한

interface IIdObject 
{ 
    int Id { get; set; } 
} 

이 포항 강판의 부분 집합이 추가 인터페이스를 구현을 :

IRepository < T>:

interface IDeletableObject : IIdObject 
{ 
    bool IsDeleted { get; set; } 
} 

나는 이런 식으로 뭔가를 보이는 저장소 계층 구조를 가지고210 : BasicRepository < T> < : ValidatingRepository < T> (T는 IIdObject입니다)

내가 IDeletableObject을 구현하는 것을 포항 강판의 모두가 Where(p => p.IsDeleted == false) 필터를 갖도록 계층 구조에 FilteringRepository를 추가하려고 해요 다른 쿼리가 수행되기 전에 적용됩니다. 내 목표는 IDeletableObjects만을위한 계층 구조 복제를 피하는 것입니다.

내 첫 번째 시도는 다음과 같이 보았다 :

public override IQueryable<T> Query() 
{ 
    return base.Query().Where(t => ((IDeletableObject)t).IsDeleted == false); 
} 

이 객체에 LINQ 잘 작동하지만, 내가 EF 백엔드로 전환 할 때 얻을 : 는 "엔티티에 LINQ는 엔터티 데이터 모델 원시 타입 캐스팅 지원 . "

는 좀 애호가 매개 변수화 된 솔루션을 시도했다,하지만 난하지 않는 몇 가지 이유로 다음과 같은 경우 T의 공변를 만들 수 없습니다 때문에 궁극적으로 확실히 이해하지 못했습니다

interface IQueryFilter<out T> // error 
{ 
    Expression<Func<T, bool>> GetFilter(); 
} 

나 ' 도움이된다면 더 복잡한 해결책에 대해 더 자세히 설명해 드리겠습니다.하지만 누군가가 나를 시도 할 수있는 아이디어가 있기를 바랍니다.

대단히 감사드립니다.

+0

비 인터페이스 유형을 사용해야합니다. EF는 인터페이스 구현을 SQL로 변환하는 방법을 모른다. –

+0

'T : IDeletableObject'를 입력하여 매개 변수를 입력 할 수 없습니까? 'Repository'로부터 상속 받고 추가 타입 제약을 가진'DeletableRepository'를 생성합니다. – LukLed

+0

@Craig : 수업을 사용할 경우 유감스럽게도 여러 가지 상속 문제가 발생합니다. :-(@LukLed : 지금 저장소 생성을 위해 IoC 컨테이너에 하나의 규칙이 있습니다.새로운 저장소 유형을 만들거나 다시 매개 변수화하는 것이 필자가 피하고자했던 추가 사양을 필요로한다고 생각합니다. – ladenedge

답변

1
이 코멘트에 대한 너무 큰

, 그래서 ...

당신은 동적 표현을 만들 수 있습니다. 나는 헬퍼 메소드를 만들었습니다

public static class ExpressionHelper 
{ 
    public static MemberExpression PropertyExpression(this Expression expr,string propertyName) 
    {   
     var properties = propertyName.Split('.'); 

     MemberExpression expression = null; 

     foreach (var property in properties) 
     { 
      if (expression == null) 
       expression = Expression.Property(expr, property); 
      else 
       expression = Expression.Property(expression, property); 
     } 

     return expression; 
    } 

    public static BinaryExpression EqualExpression<T>(this Expression expr, string propertyName, T value) 
    { 
     return Expression.Equal(expr.PropertyExpression(propertyName), Expression.Constant(value, typeof(T))); 
    } 
} 

은 그럼 당신은 사용할 수 있습니다

//Checking if T implements IDeletableObject 
if (typeof(IDeletableObject).IsAssignableFrom(typeof(T))) 
{ 
    //a 
    var parameter = Expression.Parameter(typeof(T), "a"); 
    //a.IsDeleted == false 
    var where = parameter.EqualExpression("IsDeleted", false); 
    //a => a.IsDeleted == false 
    var condition = Expression.Lambda<Func<T, bool>>(where, parameter); 
    list = list.Where(condition); 
} 

편집

또한 Dynamic Linq Library를 사용할 수 있습니다. 표현식도 사용하지만, 어떻게 작동하는지 생각하게 강요하지 않습니다. 간단한 조건을 문자열로 작성하십시오. 어떻게 bool 값을 처리하는지 모르겠습니다.

+0

매우 흥미 롭습니다 (그리고 저는 손 잡고, ㅎ) 고맙습니다. 나는 이것을 최대한 빨리 시도 할 것이다! – ladenedge

+0

@ladenedge : 정상적으로 작동하지만 조정이 필요할 수 있습니다. 나는 그것을 완전히 테스트 할 수 없었다. – LukLed

+0

음, 여기서 코드로 약간 연주했지만 Dynamic Linq는 너무 쉬웠습니다. 결과 코드는 다음과 같습니다 :'set.Where ("IsDeleted == @ 0", false)'- 매우 간단합니다! 시간을내어 도와 주셔서 감사합니다. – ladenedge

관련 문제