2011-01-12 42 views
6

Có một tập hợp các loại thiết bị, một số trong số đó hỗ trợ (các) cài đặt cấu hình. Tôi đang cố gắng lấy danh sách tất cả các loại thiết bị và mọi cài đặt có thể áp dụng.LINQ External Outer Join - DefaultIfEmpty Error

Truy vấn này không chọn các thiết bị không có DeviceParameters. Nếu tôi thêm .DefaultIfEmpty() như được hiển thị bên dưới, tôi nhận được lỗi này:

"Giá trị tham chiếu đến loại giá trị 'Int64' không thành công do giá trị vật liệu là rỗng. Tham số chung của loại kết quả hoặc truy vấn phải sử dụng một loại nullable. "

Synatx chính xác cho DefaultIfEmpty là gì?

  var Devices = from d in dc.DeviceTypes 
         join p in dc.DeviceParameters on d.TypeID equals p.TypeID into tmpTable 
         from items in tmpTable.DefaultIfEmpty() 
         group items by d.DeviceName into g 
         select new 
         { 
          DeviceName = g.Key, 
          settings = from s in g 
            select new 
            { 
             ParamName = s.ParamName, 
             Param1 = s.Param1, 
             Param2 = s.Param2, 
             Param3 = s.Param3 
            } 
         }; 
+0

Bạn đã thử truyền cả hai TypeID vào int không thể thực hiện? "on (int?) d.TypeID bằng (int?) p.TypeID thành" ... –

+0

Jacob: Cảm ơn bạn đã đề xuất, nhưng lỗi tương tự xảy ra ngay cả với dàn diễn viên. –

+0

:). Giá trị một shot và cảm ơn cho việc cập nhật. Rất vui khi bạn nhận được câu trả lời đủ điều kiện. –

Trả lời

4

Nếu bạn đã xác định mối quan hệ chính nước ngoài, tôi nghĩ rằng giải pháp là khá đơn giản, trừ khi tôi đang thiếu một cái gì đó:

var Devices = dc.DeviceTypes 
    .Select(p=>new 
     { 
      DeviceName = p.DeviceName , 
      settings = p.DeviceParameters 
       .Select(q=>new 
       { 
        ParamName = p.ParamName, 
        Param1 = q.Param1, 
        Param2 = q.Param2, 
        Param3 = q.Param3 
       }) 
     }); 

Anyways, tôi có lẽ sẽ làm các thiết lập phần theo cách này:

settings = p.DeviceParameters.ToList() 
+0

Cảm ơn! Điều đó trả về những gì tôi cần. –

+0

Fyi, p.DeviceParameters.ToList() đưa ra lỗi này: LINQ to Entities không nhận ra phương thức 'System.Collections.Generic.List'1 [Instruments.DeviceParameters] ToList [DeviceParameters] (System.Collections.Generic.IEnumerable' Phương pháp 1 [Instruments.DeviceParameters]), và phương pháp này không thể được dịch sang biểu thức cửa hàng. –

+0

Ohhh tôi hiểu rồi. Không biết nó không hoạt động theo cách đó, tôi là loại mới đối với LINQ đối với các thực thể. Thx để chia sẻ =) – Francisco

1

tôi tin rằng các vấn đề mà bạn đang nhìn thấy với truy vấn của bạn là bằng cách sử dụng các DefaultIfEmpty() gọi bạn này sau đó cố gắng để kéo giá trị ra khỏi một o rỗng bject. Nếu bạn có một DeviceType hợp lệ nhưng không có bất kỳ DeviceParameters ánh xạ sau đó khi nó đang cố gắng hiện thực hóa các thiết lập tài sản với tuyên bố này:

settings = from s in g 
select new 
{ 
    ParamName = s.ParamName, 
    Param1 = s.Param1, 
    Param2 = s.Param2, 
    Param3 = s.Param3 
} 

Nó đang cố gắng để tạo ra một đối tượng mới và đối tượng cho "s" là null nên cố truy cập thuộc tính ParamName hoặc Param1, v.v. sẽ không hoạt động. Tôi đã thử cùng một mã trong LINQPad và khi tôi loại bỏ các DefaultIfEmpty() gọi sau đó tất cả mọi thứ đã làm việc.

Nếu không biết thuộc tính và loại của chúng, tôi không thể chắc chắn nhưng như tôi đã nói, dựa trên việc triển khai mã tương tự trong LINQPad tôi nhận được kết quả tương tự.

Các vấn đề liên quan