2011-10-27 5 views
2

유형의 상수 값을 생성 할 수 없습니다. 오류 : 'mvcinfosite.ViewModels.GrpSearchHolder'유형의 상수 값을 생성 할 수 없습니다. 이 컨텍스트에서는 원시 형식 (예 : 'Int32, String 및 Guid') 만 지원됩니다.표현 트리 오류 :

오류를 어떻게 해결할 수 있습니까? 나는 내 문제를 보여주기 위해 간단한 예를 든다. 내 실제 프로젝트에서 MyGrp1, MyGrp2, MyGrp3은 ListBox로 대체됩니다. 내 데이터를 필터링하는 데 사용합니다.

 public class MyGroupHolder 
     { 
      public string GrpName { get; set; } 
      public List<int ?> ListSelectedGrpDescID { get; set; } 
     } 


     public ActionResult Index() 
     { 
      //Database Context 
      DBEntities db = EntityFactory.GetEntity(); 

      //Variables 
      List<MyGroupHolder> ListGrpHolder = new List<MyGroupHolder>(); 

      //Imagine a 3 listbox (MyGrp1,MyGrp2,MyGrp3) 
      //Each listbox contains selected value. 
      MyGroupHolder MyGrp1 = new MyGroupHolder(); 
      MyGrp1.GrpName = "Grp 1 Test"; 
      MyGrp1.ListSelectedGrpDescID = new List<int?>(); 
      MyGrp1.ListSelectedGrpDescID.Add(55); 


      MyGroupHolder MyGrp2 = new MyGroupHolder(); 
      MyGrp2.GrpName = "Grp 2 Test"; 
      MyGrp2.ListSelectedGrpDescID = new List<int?>(); 
      MyGrp2.ListSelectedGrpDescID.Add(56); 


      MyGroupHolder MyGrp3 = new MyGroupHolder(); 
      MyGrp3.GrpName = "Grp 3 Test"; 
      MyGrp3.ListSelectedGrpDescID = new List<int?>(); 
      MyGrp3.ListSelectedGrpDescID.Add(57); 

      ListGrpHolder.Add(MyGrp1); 
      ListGrpHolder.Add(MyGrp2); 
      ListGrpHolder.Add(MyGrp3); 

      //Getting a list of Locations base on the Group Filter 
      var ListLocation = db.Locations.Where(p => ListGrpHolder.Any(pg => pg.ListSelectedGrpDescID.Count == 0 || p.GroupLocations.Select(sg => sg.GrpDescID).Intersect(pg.ListSelectedGrpDescID).Any())).ToList(); 


      return View(); 
     } 

답변

1

개체를 linq-to-entities 쿼리로 전달할 수 없습니다. 값을 추출하여 조건으로 전달해야합니다. 그냥 쿼리의 시작은 문제를 보여줍니다

SQL 서버의 LINQ에 엔티티 쿼리 ListGrpHolder가 무엇인지 실행을 담당해야한다 (이 응용 프로그램의 메모리에 살고있는) 어떤 값에 포함하는 방법
.Where(p => ListGrpHolder.Any(... 

?

나는 당신의 질의와 그것이 무엇을해야 하는지를 정확히 이해하지 못한다. 그러나 linq-to-entities와 linq-to-objects는 엄밀히 구분해야한다. 첫 번째는 SQL 서버에서 실행되며 간단한 유형 만 쿼리 할 수 ​​있습니다. 두 번째는 응용 프로그램에서 실행되며 모든 객체 및 linq 구성을 사용할 수 있지만 SQL 서버의 데이터와 함께 사용하려면 먼저 모든 응용 프로그램을 응용 프로그램에로드하고 응용 프로그램의 메모리에서 필터링해야합니다 섬기는 사람.

+0

내 식을 유효한 식으로 변환하는 사용자 지정 식 트리가 있습니까? –

0

은 쿼리가 db.Locations mycalculatedlocalids.Contains (l.id) 선택 리터에 리터에서

를 사용하는 변환;

IQueryable에는 공급자 정보가 들어 있으며 IEnumerable (ListGrpHolder)에는 포함되어 있지 않습니다. 이 때문에 SQL Server에서 쿼리를 실행할 수 없습니다.

0

람다 메서드 대신 LINQ를 사용하도록 쿼리를 변환했습니다. LINQ 구문으로 작성된 쿼리를 읽는 것이 더 쉽습니다.

db.Location은 (는) pg.ListSelectedGrpDescID.Count == 0과 어떻게 관련이 있습니까? db.Location이 0이면 무엇을 반환해야합니까? 나는 지금 질의의이 부분을 버렸다.

해결책을 찾으려고 할 때 문제를 단계별로 구분하는 것이 좋습니다. 이것은 해결책을 향한 첫 걸음입니다.

먼저 ListGrpHolder ID를 다른 명령문으로 리팩토링 할 수 있습니다. 이렇게하면 int 값만 반환되고 ListLocation 쿼리를 더 쉽게 읽을 수 있습니다.

var SelectedIds = ListGrpHolder.Select(pg => pg.ListSelectedGrpDescID).SelectMany(i => i); 
var ListLocation = (from loc in db.Locations 
        from grp in loc.GroupLocations 
        where SelectedIds.Contains(grp.GrpDescID) 
        select loc).ToList(); 

필요한 결과를 얻기 위해 쿼리를 단순화하거나 변경하지 못하면 식 트리를 사용할 수 있습니다.