2013-05-17 1 views
1

나는 오래 동안 나를 괴롭히는 문제에 대한 우아하고 재사용 가능한 솔루션을 찾고 있습니다. 따라서, linq-sql 문에서 사용자 지정 메서드 또는 대리자 사용

는 내가 모든 사이트를 통해 사용하는 일부 비즈니스 로직을 말해봐 :

public DateTime ExpiryDate 
{ 
    get { return DateAdded.Date.AddMonths(ApplicationConfiguration.Rule3ExpiryLengthInMonths); } 
} 

그리고 Linq에 문 (, 그것은 복잡 할 수있는이 얼마나 간단한에 관해서는 개최되지 않음) :

groupedByPatient.Count(x => 
         x.Max(a => System.Data.Objects.EntityFunctions.AddMonths(a.DateAdded, ApplicationConfiguration.Rule3ExpiryLengthInMonths)) 
         <= DateTime.Now); 

이 "만료 된"논리는 (이해할 만하게) 반복되어야합니다. 만료 된 열은 db가 아닙니다. 결과적으로 우리는 코드 전체에 분산 된 비즈니스 로직을 갖게됩니다. 이상적으로 우리는 할 것이다 :

var count = groupedByPatient.Count(x => 
         x.Max(a => a.ExpiryDate) 
         <= DateTime.Now); 

을 이론적으로 당신이, 당신이 코드 밖으로 추상적 할 수 있어야 Linq에의 "C#을"규칙을 준수 말한대로 :

public DateTime ExpiryDate 
    { 
     get { return System.Data.Objects.EntityFunctions.AddMonths(
       DateAdded, ApplicationConfiguration.Rule3ExpiryLengthInMonths).D } 
    } 
+0

나는 여기 혼란이 groupedByPatient를 사용하고 있다고 생각합니다. 그 결과가 이미 구체화되었거나 DataContext.Patients. [grouping query]가 될 것입니다. 해결책은 아주 다릅니다. – Gats

답변

0

왜 당신이를 작성하지 않습니다 extension method on DateTime?

static class DateTimeExtensions 
{ 
    public static DateTime ExpiryDate(this DateTime dte) 
    { 
     return dte.AddMonths(ApplicationConfiguration.Rule3ExpiryLengthInMonths); 
    } 
} 

내가 정확하게 예제를 이해한다면, DateAdded 당신이 만료을 찾고자있는 테이블의 날짜 열이있다 : 당신이 데이트를 할 때마다 그런 식으로, 당신은 당신의 유효 기간을 얻을 것을 호출 할 수 있습니다 날짜.

var count = groupedByPatient.Count(x => 
         x.Max(a => a.DateAdded.ExpiryDate()) <= DateTime.Now); 
+0

내가 찾고있는 해결책은 이것을 반드시 수행하는 것이 아니라 어떻게 링크 문 내에서 C# 메서드를 사용하는 것입니다. 이 만료 방법은 무엇이든 될 수 있습니다. Linq가 현재 SQL에이를 수는 없기 때문에 재사용 가능한 좋은 솔루션을 생각하려고합니다. 목적은 재사용 가능한 비즈니스 로직을 Linq 문에서 추상화하는 것입니다. – GarethReid

+0

@GarethReid : 물론, 모든 C# 문은 LINQ와 함께 사용할 수 있습니다.하지만 LINQ to Entity Framework 또는 LINQ to SQL과 함께 사용할 필요는 없습니다. 특히 * Objects *에 LINQ를 사용하는 경우 유효한 C#을 사용할 수 있습니다. 그 이유는 물론 여러분의 방법이 예를 들어서 사용할 수 있기 때문입니다.LINQ를 EF로 변환하려면 LINQ 쿼리를 EF 쿼리 (SQL과 비슷하게 보임)로 변환 할 수 있어야하지만 일반적으로 불가능합니다. 따라서 논리의 복잡성에 따라 db에서 모든 * 객체를 가져 와서 결과 집합에 대한 쿼리에서 C# 메서드를 사용해야 할 수도 있습니다. –

0

내가 당신에 입력 한 코드 샘플 대이 주제에서 잘 모르겠어요,하지만 난 당신이 찾고있는 무슨 여기에 2 인 확신 : 그럼, 그냥 이렇게.

그냥 (당신이 데이터를 가지고 즉 후) 구체화 된 쿼리의 결과를 원하는 경우, 사용 확장 :

public static string ToExpiryDate(this DateTime date) 
{ 
    return date.AddMonths(ApplicationConfiguration.Rule3ExpiryLengthInMonths); 
} 

당신의 (a 된 IQueryable 내에서 결과를 원하는 경우에 당신의 주제로하는

var count = groupedByPatient.Count(x => x.YourEntities(MaxExpiryDate) <= DateTime.Now); 
:

public static Expression<Func<IEnumerable<YourEntity>, DateTime>> MaxExpiryDate = (y) => y.Max(
    System.Data.Objects.EntityFunctions.AddMonths(y.DateAdded, ApplicationConfiguration.Rule3ExpiryLengthInMonths) 
); 

그런 다음 쿼리가 같을 것이다 : 당신이) 내가 생각을 찾고있다, 당신은 표현식을 사용할 수 있습니다

참고 : Func <>은 식 으로 감싸 야합니다. 식에서 래핑하지 않고 둘 다 작동하는 것으로 보일지라도 쿼리는 실행 전에 materialization을 강제로 수행합니다. 함수 주위에 표현식을 두어 EF에게 쿼리의 일부로 처리하도록 지시합니다.

+0

나는 네가 여기서 뭘하고 있는지 알아. 나는 약간의 표현으로 연주했지만 운이 없었습니다. 나는 약간의 연극을 가지고 당신에게 알려줄 것입니다. – GarethReid

관련 문제