2013-09-21 43 views
109

Tôi nhận được lỗi này cho truy vấn dưới đâyKhông thể để tạo ra một giá trị không đổi kiểu Chỉ loại nguyên thủy hoặc các loại liệt kê được hỗ trợ trong bối cảnh này

Không thể để tạo ra một giá trị không đổi kiểu API.Models.PersonProtocol. Chỉ loại hoặc các loại liệt kê nguyên thủy được hỗ trợ trong bối cảnh này

ppCombined dưới đây là một đối tượng IEnumerable của PersonProtocolType, được xây dựng bởi concat của 2 PersonProtocol danh sách.

Tại sao điều này không thành công? Chúng tôi không thể sử dụng mệnh đề LINQ JOIN bên trong của SELECT của một JOIN?

var persons = db.Favorites 
    .Where(x => x.userId == userId) 
    .Join(db.Person, x => x.personId, y => y.personId, (x, y) => 
     new PersonDTO 
     { 
      personId = y.personId, 
      addressId = y.addressId,     
      favoriteId = x.favoriteId, 
      personProtocol = (ICollection<PersonProtocol>) ppCombined 
       .Where(a => a.personId == x.personId) 
       .Select(b => new PersonProtocol() 
       { 
        personProtocolId = b.personProtocolId, 
        activateDt = b.activateDt, 
        personId = b.personId 
       }) 
     }); 
+0

liên quan: [ LINQ, Không thể tạo giá trị không đổi của loại XXX. Chỉ các kiểu nguyên thủy hoặc kiểu liệt kê mới được hỗ trợ trong ngữ cảnh này] (http://stackoverflow.com/q/13405568/456814). –

+0

Liên quan: [Không thể tạo giá trị không đổi - chỉ các loại nguyên thủy] (http://stackoverflow.com/q/10862491/456814). –

Trả lời

157

này không thể làm việc vì ppCombined là một bộ sưu tập của các đối tượng trong bộ nhớ và bạn không thể tham gia vào một loạt các dữ liệu trong cơ sở dữ liệu với một tập hợp các dữ liệu đó là trong bộ nhớ. Bạn có thể thử thay vì để trích xuất các mặt hàng lọc personProtocol của bộ sưu tập ppCombined trong bộ nhớ sau bạn đã truy xuất các tài sản khác từ cơ sở dữ liệu:

var persons = db.Favorites 
    .Where(f => f.userId == userId) 
    .Join(db.Person, f => f.personId, p => p.personId, (f, p) => 
     new // anonymous object 
     { 
      personId = p.personId, 
      addressId = p.addressId, 
      favoriteId = f.favoriteId, 
     }) 
    .AsEnumerable() // database query ends here, the rest is a query in memory 
    .Select(x => 
     new PersonDTO 
     { 
      personId = x.personId, 
      addressId = x.addressId, 
      favoriteId = x.favoriteId, 
      personProtocol = ppCombined 
       .Where(p => p.personId == x.personId) 
       .Select(p => new PersonProtocol 
       { 
        personProtocolId = p.personProtocolId, 
        activateDt = p.activateDt, 
        personId = p.personId 
       }) 
       .ToList() 
     }); 
+3

Phần quan trọng đối với tôi là thêm .AsEnumerable() // truy vấn cơ sở dữ liệu kết thúc tại đây, phần còn lại là truy vấn trong bộ nhớ – Sameer

+2

@Slauma Vì vậy, nếu tôi lo ngại về hiệu năng, tôi nên tránh thực hiện điều này vì nó sẽ tải tất cả dữ liệu trong bộ nhớ đầu tiên và sau đó truy vấn nó. Tôi có nên viết sql thô cho các tình huống này không? – Arvand

+0

Có vẻ như @Arvand có một điểm tuyệt vời. Nếu bạn có một số lượng lớn các bản ghi trước bộ lọc, điều này có thể mất một lượng lớn các tài nguyên bộ nhớ có sẵn. – spadelives

2

Không biết nếu có ai tìm kiếm này. Tôi gặp vấn đề tương tự. Một lựa chọn trên truy vấn và sau đó làm nơi (hoặc tham gia) và sử dụng biến chọn giải quyết vấn đề cho tôi. (vấn đề là trong bộ sưu tập "Reintegraties" đối với tôi)

query.Select(zv => new 
      { 
       zv, 
       rId = zv.this.Reintegraties.FirstOrDefault().Id 
      }) 
      .Where(x => !db.Taken.Any(t => t.HoortBijEntiteitId == x.rId 
              && t.HoortBijEntiteitType == EntiteitType.Reintegratie 
              && t.Type == TaakType)) 
      .Select(x => x.zv); 

hy vọng điều này giúp bất cứ ai.

+5

'zv.this.Reintegraties.FirstOrDefault(). Id' tiềm năng NullReferenceException –

0

Trong trường hợp của tôi, tôi đã có thể giải quyết vấn đề bằng cách làm như sau:

tôi đã thay đổi mã của tôi từ này:

var r2 = db.Instances.Where(x => x.Player1 == inputViewModel.InstanceList.FirstOrDefault().Player2 && x.Player2 == inputViewModel.InstanceList.FirstOrDefault().Player1).ToList(); 

Để này:

var p1 = inputViewModel.InstanceList.FirstOrDefault().Player1; 
var p2 = inputViewModel.InstanceList.FirstOrDefault().Player2; 
var r1 = db.Instances.Where(x => x.Player1 == p1 && x.Player2 == p2).ToList(); 
Các vấn đề liên quan