2016-08-31 1 views
2

두 개의 Entity Framework 모델이 구조가 동일하며 오라클 DB의 코드 우선을 사용하여 생성되었습니다 (2 개의 "트윈"테이블은 사용하지 마십시오. 이유를 물어보십시오. DB에 대한 제어권이 없습니다.)Entity Framework 6 + Oracle 구조가 동일한 두 테이블을 쿼리하는 방법

Linq와 동일한 쿼리를 두 번 다시 작성하지 않으려 고하는 효율적인 방법을 찾고있었습니다.

몇 가지 예 :

[Table("ORACLE.TABLE1")] 
public partial class MyModel1 
{ 
    [Key] 
    [Column(Order = 0)] 
    [StringLength(3)] 
    public string field1 { get; set; } 

    [Key] 
    [Column(Order = 1)] 
    [StringLength(3)] 
    public string field2 { get; set; } 

    [Key] 
    [Column(Order = 2)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int field3 { get; set; } 

    // -- many other fields 

} 

[Table("ORACLE.TABLE2")] 
public partial class MyModel2 
{ 
    [Key] 
    [Column(Order = 0)] 
    [StringLength(3)] 
    public string field1 { get; set; } 

    [Key] 
    [Column(Order = 1)] 
    [StringLength(3)] 
    public string field2 { get; set; } 

    [Key] 
    [Column(Order = 2)] 
    [DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public int field3 { get; set; } 

    // -- many other fields, same as above 
} 

어딘가에, 내가 가진 :

 var result1 = from t in db.MyModel1s 
         where t.field1 == myparameter1 
         && t.field2 == myparameter2 
         && t.field3 == myparameter3 
         select t; 

     var result2 = from t in db.MyModel2s 
         where t.field1 == myparameter1 
         && t.field2 == myparameter2 
         && t.field3 == myparameter3 
         select t; 
     var result = result1.ToList(); 

... 그리고 마지막으로 :

public virtual DbSet<MyModel1> MyModel1s { get; set; }  
    public virtual DbSet<MyModel2> MyModel2s { get; set; } 

데이터를 가져 오는에 대한 나의 현재의 사소한 못생긴 솔루션이있다 ...

 foreach (var res2 in result2) 
     { 
      var m1 = new MyModel1 
      { 
       field1 = res2.field1, 
       field2 = res2.field2, 
       field3 = res3.field3 
      }; 
      result.Add(m1); 
     } 

이제 result에 내가 원하는 모든 것이 포함되어 있습니다. 더 좋은 방법, 제안이 있어야합니까?

답변

2

당신은 SQL에서 UNION ALL에 해당이 사용 Concat 확장 메서드처럼 뭔가를 할 수 있습니다

var result= db.MyModel1s.Where(m=>m.field1 == myparameter1 
            && m.field2 == myparameter2 
            && m.field3 == myparameter3) 
          .Select(t=>new MyModelDTO 
             { 
             field1 = t.field1, 
             field2 = t.field2, 
             field3 = t.field3 
             } 
            ) 
          .Concat(db.MyModel2s.Where(t=> t.field1 == myparameter1 
                 && t.field2 == myparameter2 
                 && t.field3 == myparameter3) 
               .Select(t=>new MyModelDTO 
                  { 
                  field1 = t.field1, 
                  field2 = t.field2, 
                  field3 = t.field3 
                  } 
                 ) 
            ).ToList(); 

이 방법 당신은 당신의 DB를 왕복에 결과를 얻을 것이다. 중복을 피하려면 Union 확장 방법을 사용하십시오.

var result= db.MyModel1s.Where(m=>m.field1 == myparameter1 
            && m.field2 == myparameter2 
            && m.field3 == myparameter3) 
          .AsEnumerable()// Calling the method you will call Concat extension method from IEnumerable<T> type 
          .Concat(db.MyModel2s.Where(t=> t.field1 == myparameter1 
                 && t.field2 == myparameter2 
                 && t.field3 == myparameter3) 
               .Select(t=>new MyModel1 
                  { 
                  field1 = t.field1, 
                  field2 = t.field2, 
                  field3 = t.field3 
                  } 
                 ) 
            ).ToList(); 
+0

사실,이 때문에 작동하지 않습니다 : http://stackoverflow.com/questions/5325797/the-entity-cannot-be-constructed-in-a-linq-to-entities-query 그리고 난 DTO를 매핑 된 엔티티와 연결할 수 없기 때문에 DTO를 만들 수 없습니다. – tonjo

+0

맞습니다. 잊어 버렸습니다. 동일한 DTO를 사용하여 두 쿼리를 모두 투영 할 수 있습니까? 제 생각에는 서버 측에서이 쿼리를 실행하는 것이 가장 좋은 해결책이라고 생각합니다. 그렇지 않으면 데이터베이스를 두 번 왕복하고 두 결과를 메모리에 병합해야합니다. 당신은'AsEnumerable' 확장 메소드를 사용하여 하나의 쿼리에서 그렇게 할 수 있습니다.이 마지막 아이디어에 대한 도움이 필요합니까? – octavioccl

+0

Remus가 제안한대로 DBA에게 뷰 생성을 요청해야한다고 생각합니다. 그렇지 않으면 네 마지막 아이디어에 대한 도움이 필요합니다. – tonjo

1

보기를 만들기 : 공통 DTO에 두 쿼리를 투사하지 않으려면

지금, 당신은 당신의 DB에 두 개의 왕복을하고 메모리에 병합을 수행해야합니다 두 테이블 간의 UNION ALL을 수행하는 DB에서 뷰를 대신 쿼리하십시오. 이 아니고이 노조 클라이언트 쪽을 수행하면 가능한 서버 측 최적화가 누락되어 두 테이블 모두에서 올바른 순서와 같은 특정 의미를 제공 할 수 없습니다.

+0

내가 말했듯이 나는 DB를 제어 할 권한이 없다. 어쩌면 ... – tonjo

+0

테이블 구조를 수정하거나 하나의 테이블 만 사용하도록 앱에 요청하면 큰 변화가 생길 것입니다. 뷰를 선언하는 것은 그렇게 중요하지 않습니다. –

+0

아무런 통제력이 없다면, 모든 변화가 "많이"될 수 있습니다. 어쨌든 고마워요. – tonjo

관련 문제