2013-02-27 2 views
1

두 개의 다른 DB에서 두 모델에 대한 이상한 조인 방법처럼 보일 수 있습니다. 첫 번째 쿼리를 수행 한 다음 작은 ID 목록을 검색하여 검색 할 수 있습니다. 또 다른 DB. 모든 일을 ok 바 하나 또는 두 가지, 난 람다 함수를 사용하여 하위 목록 하위 쿼리를 할 수 없어, 나는 ID를 선택기 함수를 일반하지만 그게 지금 내가 소스 유형을 연결할지 모르겠 어디 조항에서 링크를 가지고 있어요 id에 전달 된 함수에 객체가 있으므로 .Where(TSource => idlist.Contains(Idselector) 예제 코드가 List.Conatins 코드 때문에 파손되는 위치까지 아래에 있습니다. 사람이 크게 감사하겠습니다 도움이 될 수 있다면 나는 stook 나처럼SourceB에서 SourceA에서 ID가있는 모든 요소를 ​​가져옵니다.

public static Foo JoinTwoModels<T1,T2>(
      DbSet Dbs1, 
      DbSet Dbs2, 
      Expression<Func<T1, object>> Id1, 
      Expression<Func<T1, dynamic>> Selector1, 
      Expression<Func<T1, bool>> Search1, 
      Expression<Func<T2, object>> Id2, 
      Expression<Func<T2, dynamic>> Selector2) 
     { 
      var Output1 = Queryable.OfType<T1>(Dbs1); 

      var Output2 = Queryable.OfType<T2>(Dbs2); 

      List<dynamic> Result1 = Output1.Where(Search1).Select(Selector1).ToList(); 

      List<object> idList = new List<object>(); 

      PropertyInfo p1 = Result1[0].GetType().GetProperty("Id"); 

      foreach (var o1 in Result1) 
      { 
       idList.Add(p1.GetValue(o1)); 
      } 

      //Query result entries into db 
      List<T2> Result2 = Output2.Where(idlist.contains(Id2)).ToList(); 

답변

0

어떻게 이런 일에 대해 : 당신은 확실히 밝혀지지 않았다 싶었다 무엇

public class Foo 
{ 
    public int Context; 
    public string Data; 
} 

public class Bar 
{ 
    public int Context; 
    public string Data; 
} 

public static IEnumerable<TOutput> JoinTwoModels<T1, T2, TIdent, TOutput>(
    IEnumerable<T1> sourceA, 
    IEnumerable<T2> sourceB, 
    Func<T1, TIdent> idSelectorA, 
    Func<T2, TIdent> idSelectorB, 
    Func<T1, TOutput> selectorA, 
    Func<T2, TOutput> selectorB) 
{ 

    var quearyA = sourceA 
      .Select(x => new {Value = selectorA(x),Id = idSelectorA(x)}); 

    var quearyB = sourceB 
      .Select(y => new {Value = selectorB(y),Id = idSelectorB(y)}) 
      .Where(y => quearyA.Select(x => x.Id).Contains(y.Id)) 
      .Select(y => y.Value); 


    return quearyA.Select(x => x.Value).Concat(quearyB); 
} 

private static void Main(string[] args) 
{ 
    var sourceA = new List<Foo>() {new Foo() {Context = 2, Data = "I'm a Foo"}}; 
    var sourceB = new List<Bar>() {new Bar() {Context = 2, Data = "I'm a Bar"}}; 

    var Output1 = sourceA.AsQueryable(); 
    var Output2 = sourceB.AsQueryable(); 

    var results = JoinTwoModels(
     Output1, 
     Output2, 
     (Func<Foo, int>) (x => x.Context), 
     (Func<Bar, int>) (x => x.Context), 
     (Func<Foo, string>) (x => x.Data), 
     (Func<Bar, string>) (x => x.Data)); 

    foreach (var item in results) 
     Console.WriteLine(item); 
} 

; 그래서 위에서 공통 컨텍스트 (id)를 공유하고 변환 된 공통 유형으로 반환하는 Source-A (유형 Foo) 및 Source-B (Bar 유형)의 모든 항목을 선택하고 있습니다.

당신은 당신이 단지 B의 값을 원하는 경우에,이를 단순화 할 수 있습니다 : 답장을 보내

var quearyA = sourceA.Select(idSelectorA); 

var quearyB = sourceB 
     .Select(y => new {Value = selectorB(y),Id = idSelectorB(y)}) 
     .Where(y => quearyA.Select(x => x).Contains(y.Id)) 
     .Select(y => y.Value); 

return quearyB; 
+0

감사 다윗을 도와, 당신은 내가 이드에 함께 두 결과에 가입하고 싶다고 정확하지만, 나는 동적/동적 필드를 반환 할 때마다 여러 필드를 선택할 수있는 유연성을 원했지만 매개 변수가 고정 된 값/ID 속성으로 고정되었거나 숫자 필드에서 동적으로 반환되는 것은 확실하지 않습니까? 또한이 linq - 개체 IEnumberable 쿼리를 것 같다,이 DB에 IQueryable 동일하게 작동합니까? 다시 한 번 감사드립니다. – Gerard

+0

첫째, IEnumerable은 결과를 반복 할 때까지 실행되지 않습니다. 그래서 당신은 IEnumerables를 IQueryable의 최상위에서 실행하는 것이 안전하다고 생각합니다 (시도한 적은 없지만). 동적 인 경우; 동적 인 문제는 컴파일 타임에서 런타임으로 이동합니다. 난 그것을 피하기 위해 강력하게 입력 ... 푸, T1, T2 및 TOutput 아무것도 될 수 있습니다. 하지만 데이터베이스에 ID와 VALUE라는 두 개의 열이 있고 VALUE 유형이 행마다 바뀌지 않는다고 생각합니다. –

+0

또한 두 가지 문제를 섞지 마십시오. 일치하는 ID로 값을 가져옵니다. 그것은 IEnumerable ...으로 반환됩니다. 쿼리로 변환하고 데이터 필드 선택을 실행합니다. 즉, T1 및 T2를 IQueryable로 가질 수 있습니다. 등 ... –

관련 문제