2012-06-15 3 views
3

으로 일반적인 속성을 설정하는 방법은 다음과 같이 여러 쿼리가 있습니다 LINQ 선택

var query = from a in EntityAs 
      select new EntityASmall() 
      { 
       // Common Stuff: 
       Id = a.Id, 
       Name = a.Name, 
       ShortName = a.ShortName, 
       // Specific to EntityA: 
       ASpecificProperty1 = a.1, 
       ASpecificProperty2 = a.2 
      }; 

var query = from b in EntityBs 
      select new EntityBSmall() 
      { 
       // Common Stuff: 
       Id = b.Id, 
       Name = b.Name, 
       ShortName = b.ShortName, 
       // Specific to EntityB: 
       BSpecificProperty1 = b.1, 
       BSpecificProperty2 = b.2 
      }; 

EntityA 및 EntityB 모두 Id, NameShortName 속성이 공통 기본 클래스에서 파생됩니다. EntityASmallEntityBSmall에 대해서도 동일합니다. 나는 이처럼 많은 쿼리를 가지므로 먼저 공통적 인 것들을 가져 오는 일종의 축약 쿼리를 ​​만들고 싶습니다.

public static TSource SetCommonProperties<TSource>(this TSource input, EntityBaseClass entity, Action<TSource> updater) where TSource : EntitySmallBase 
{ 
    input.Id = entity.Id; 
    input.Name = entity.Name; 
    input.ShortName = entity.Name; 

    updater(input); 

    return input; 
} 

내가 그렇게처럼 사용할 수 있습니다 :

var query = from a in EntityAs.AsEnumerable() 
      select new EntityASmall().SetCommonProperties(a, x => 
      { 
       ASpecificProperty1 = x.1; 
       ASpecificProperty2 = x.2; 
      }); 

참고 AsEnumerable() I는 다음과 같습니다 다소 유망한 확장 방법을 발견했다. 그것 없이는, "성명을 가진 람다식이 표현식 트리로 변환 될 수 없다"는 것을 알 수 있습니다. 이것은 대략 Action 부분을 LINQ-to-SQL의 표현식으로 변환하려고한다는 것을 의미합니다. AsEnumerable()처럼 컬렉션을 로컬로 가져 오는 것 같습니다. 길어진 게시물에 대해 유감이지만 LINQ-to-SQL 및 Entity Framework에서 사용할 수있는 표현식이 있습니까? 미리 감사드립니다.

+0

'EntityAs'는'IQueryable <>'입니까? –

+0

'TEntity' 타입의 매개 변수를 취하고'TEntitySmall'로 변환하는 일반적인 메소드'ProjectOntoSmall'을 쓸 수 없습니까?기본 형식에서 파생되어야하는 이러한 형식 매개 변수에 제약 조건을 넣으면 작동합니다. –

답변

0

제공되는 확장 방법은 괜찮습니다.

단지 파생 된 모든 엔티티에 대해 생성해야하며, 여러 개의 엔티티가있는 것처럼 보이므로 문제가 될 수 있습니다.

두 번째로 나는 당신이 실제로 당신의 확장 메소드에서 그 액션 델리게이트를 전달할 필요가 있다고 생각하지 않는다. 가능한 경우 해당 메소드를 호출하십시오. 나는 디자인에 대해 많이 모른다.

그래서 확장 방법뿐만 아니라 다음과 같이 그런 다음 extesion 방법을 사용할 수 있습니다이

public static TSource SetCommonProperties<TSource>(this TSource input, EntityBaseClass entity)  where TSource : EntitySmallBase 
{ 
    input.Id = entity.Id; 
    input.Name = entity.Name; 
    input.ShortName = entity.Name; 

    this.Update(input); // Or this method could exist in any other class or static class. 

    return input; 

}

과 같을 것이다.

var query = from a in EntityAs 
     select new EntityASmall 
     {  
      ASpecificProperty1  
      ASpecificProperty2  
     }).SetCommonProperties(a,entity)  

이렇게하면 AsEnumerable을 사용하지 않아도됩니다. 당신이 좋아 원하는 경우 또한 같은 방법으로 방법을 derviced하기 위해베이스에서 변환 할 수 있습니다 :

DerivceEntityObject SetCommonProperties(BaseEntity) 

나는 이것이 당신에게 내가 여기에 제안하는 것을 시도하고있는 무슨 아이디어를 제공 바랍니다.

+0

흠, LINQ-to-SQL에서는 작동하지만 EF에서는 작동하지 않습니다. SetCommonProperties를 SQL로 변환 할 수 없다는 불평을합니다. 나는 LINQ-to-SQL에서 LINQ-to-SQL과 LINQ-to-Objects 사이에 선이 좀 더 흐려지기 때문에 LINQ-to-SQL에서 작동한다고 추측합니다. – Ocelot20

+0

예 나는 그 EF 것을 놓친 것에 동의합니다. SQL에서 메소드를 변환하려고 시도하면 불평 할 것이다. 이 경우 당신이 할 수있는 것은이 핵심 작업을 제거하고 (더 이상의 확장 방법이 아님) 내가 언급 한 것과 같은 방식으로 일반적인 방법으로 사용하는 것입니다. – Tabish

+0

예 : EntityAs Select SetCommonProperties (a, 엔티티)를 선택한 다음 수행중인 작업을 선택합니다. – Tabish

1

코드를 항상 건조하게 만드는 것이 좋습니다. 일부 수고와 노동 및 일부 Expression 부두와 작업하는 방식을 취할 수도 있지만,이 링크를 좋아할 것입니다. : Stop using AutoMapper in your Data Access Code. (AutoMapper를 사용하지 않더라도).

작품이 좋은 작품으로는 같은 간결한 문장을 쓸 수 있습니다 :

context.EntityAs.Project().To<EntityASmall>(); 
context.EntityBs.Project().To<EntityBSmall>(); 

나는처럼 정말 나 자신과 내가 사용했습니다.

+0

좋은 링크. 나는 그것을 좋아하지 만 불행히도 꽤 간단한 매핑이 아니라면 도움이되지 않는다. 나는 조금 더 강력한 것을 필요로한다. – Ocelot20