2013-04-04 16 views
8

Tôi có một khối mã cố gắng truy vấn một số tham số cấu hình đơn giản từ cơ sở dữ liệu. Tuy nhiên, sử dụng mã dưới đây, ngay sau khi tôi liệt kê kết quả tôi nhận được giá trị đầu tiên cho mỗi mục trong kết quả:Tại sao việc lặp qua IQueryable cho giá trị đầu tiên cho mỗi mục trong kết quả?

var db = new ConfigurationServiceDataContext("Server=vsdcs022.aridev.lcl;Database=ConfigurationService;Trusted_Connection=True;"); 

var parameters = 
    from configContents in db.ConfigurationContents 
    where 
     configContents.ConfigurationContextsTable.ConfigurationContextName == contextName && 
     configContents.ConfigurationSectionTable.ConfigurationSectionName == sectionName 
    select configContents; 

// print stuff for debugging purposes: 
foreach (var parameter in parameters) 
{ 
    Console.WriteLine("key = '{0}', value = '{1}'", parameter.ConfigurationKey, parameter.ConfigurationValue); 
} 

return parameters.ToDictionary(parameter => parameter.ConfigurationKey, parameter => parameter.ConfigurationValue); 

Nếu tôi in kết quả (trước khi thử để thêm chúng vào một cuốn từ điển mới) Tôi có được một cái gì đó như:

key = 'key1', value = 'value1' 
key = 'key1', value = 'value1' 
key = 'key1', value = 'value1' 

Nhưng nếu tôi thay thế chọn phù hợp với một loại vô danh, nó hoạt động tốt:

select new { configContents.ConfigurationKey, configContents.ConfigurationValue }; 

với điều này loại vô danh, tôi nhận được kết quả sau:

key = 'key1', value = 'value1' 
key = 'key2', value = 'value2' 
key = 'key3', value = 'value3' 

Tôi đã nghiên cứu này trong một vài giờ tại không có kết quả và trong khi tôi chỉ có thể gọi nó là tốt với các loại vô danh, điều này thực sự làm phiền tôi. Tôi đã thấy rất nhiều ví dụ cho thấy khối mã đầu tiên của tôi sẽ hoạt động tốt. Tôi chắc chắn rằng tôi đang làm điều gì đó ngớ ngẩn, tôi chỉ không thể nhìn thấy nó!

Bất kỳ ý tưởng nào?

Sau đây là đầy đủ các chi tiết của mô hình tôi đang sử dụng bắt đầu với việc thực hiện DataContext:

using System.Data.Linq; 
using Ari.Core.ConfigurationService.LinqEntityClasses; 

namespace Ari.Core.ConfigurationService 
{ 
    class ConfigurationServiceDataContext : DataContext 
    { 
     public Table<ConfigurationContentsTable> ConfigurationContents; 
     public Table<ConfigurationContextsTable> ConfigurationContexts; 
     public Table<ConfigurationSectionsTable> ConfigurationSections; 

     public ConfigurationServiceDataContext(string connectionString) : base(connectionString) {} 
    } 
} 

Bảng nội dung cốt lõi được đại diện bởi lớp thực thể ConfigurationContentsTable tôi:

using System.Data.Linq; 
using System.Data.Linq.Mapping; 

namespace Ari.Core.ConfigurationService.LinqEntityClasses 
{ 
    [Table(Name = "ConfigurationContents")] 
    class ConfigurationContentsTable 
    { 
     private long _configurationContextId; 
     private string _configurationKey; 
     private string _configurationValue; 
     private EntityRef<ConfigurationContextsTable> _configurationContextsTable; 
     private EntityRef<ConfigurationSectionsTable> _configurationSectionsTable; 

     public ConfigurationContentsTable() 
     { 
      _configurationContextsTable = new EntityRef<ConfigurationContextsTable>(); 
      _configurationSectionsTable = new EntityRef<ConfigurationSectionsTable>(); 
     } 

     [Column(Storage = "_configurationContextId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true, 
      IsDbGenerated = true)] 
     public long ConfigurationContextId 
     { 
      get { return _configurationContextId; } 
     } 

     [Column(Storage = "_configurationKey")] 
     public string ConfigurationKey 
     { 
      get { return _configurationKey; } 
      set { _configurationKey = value; } 
     } 

     [Column(Storage = "_configurationValue")] 
     public string ConfigurationValue 
     { 
      get { return _configurationValue; } 
      set { _configurationValue = value; } 
     } 

     [Association(Storage = "_configurationContextsTable", OtherKey = "ConfigurationContextId")] 
     public ConfigurationContextsTable ConfigurationContextsTable 
     { 
      get { return _configurationContextsTable.Entity; } 
      set { _configurationContextsTable.Entity = value; } 
     } 

     [Association(Storage = "_configurationSectionsTable", OtherKey = "ConfigurationSectionId")] 
     public ConfigurationSectionsTable ConfigurationSectionTable 
     { 
      get { return _configurationSectionsTable.Entity; } 
      set { _configurationSectionsTable.Entity = value; } 
     } 
    } 
} 

Hai các bảng liên kết khá đơn giản và chỉ tồn tại cho các mục đích bình thường hóa. Chúng được biểu diễn như sau:

using System.Data.Linq; 
using System.Data.Linq.Mapping; 

namespace Ari.Core.ConfigurationService.LinqEntityClasses 
{ 
    [Table(Name = "ConfigurationContexts")] 
    class ConfigurationContextsTable 
    { 
     private long _configurationContextId; 
     private string _configurationContextName; 
     private EntityRef<ConfigurationContentsTable> _configurationContentsTable; 

     public ConfigurationContextsTable() 
     { 
      _configurationContentsTable = new EntityRef<ConfigurationContentsTable>(); 
     } 

     [Column(Storage = "_configurationContextId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true, 
      IsDbGenerated = true)] 
     public long ConfigurationContextId 
     { 
      get { return _configurationContextId; } 
     } 

     [Column(Storage = "_configurationContextName")] 
     public string ConfigurationContextName 
     { 
      get { return _configurationContextName; } 
      set { _configurationContextName = value; } 
     } 

     [Association(Storage = "_configurationContentsTable", ThisKey = "ConfigurationContextId")] 
     public ConfigurationContentsTable ConfigurationContentsTable 
     { 
      get { return _configurationContentsTable.Entity; } 
      set { _configurationContentsTable.Entity = value; } 
     } 
    } 
} 

Và cuối cùng:

using System.Data.Linq; 
using System.Data.Linq.Mapping; 

namespace Ari.Core.ConfigurationService.LinqEntityClasses 
{ 
    [Table(Name = "ConfigurationSections")] 
    class ConfigurationSectionsTable 
    { 
     private long _configurationSectionId; 
     private string _configurationSectionName; 
     private EntityRef<ConfigurationContentsTable> _configurationContentsTable; 

     public ConfigurationSectionsTable() 
     { 
      _configurationContentsTable = new EntityRef<ConfigurationContentsTable>(); 
     } 

     [Column(Storage = "_configurationSectionId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true, 
      IsDbGenerated = true)] 
     public long ConfigurationSectionId 
     { 
      get { return _configurationSectionId; } 
     } 

     [Column(Storage = "_configurationSectionName")] 
     public string ConfigurationSectionName 
     { 
      get { return _configurationSectionName; } 
      set { _configurationSectionName = value; } 
     } 

     [Association(Storage = "_configurationContentsTable", ThisKey = "ConfigurationSectionId")] 
     public ConfigurationContentsTable ConfigurationContentsTable 
     { 
      get { return _configurationContentsTable.Entity; } 
      set { _configurationContentsTable.Entity = value; } 
     } 
    } 
} 
+2

Câu hỏi hay! Vui lòng gửi mã 'in kết quả' của bạn (mã của bạn có vẻ tốt, tại thời điểm nghi ngờ của tôi là bạn đang truy cập một đóng cửa được sửa đổi trong mã in) –

+0

Bạn có thể đăng mã in kết quả (không chính xác) không? – Rob

+1

Mùi giống như đóng cửa sửa đổi. – ken2k

Trả lời

0

Vì vậy, sau khi đào sâu thêm và xem xét mã của tôi, tôi thấy hai vấn đề đó, khi sửa chữa, mang lại kết quả mong đợi.

Đầu tiên, trong lớp thực thể ConfigurationContentsTable, trường PK của tôi được cấu hình để xem ConfigurationContextId thay vì trường ConfigurationContentId. Khi tôi sửa lỗi này, tôi bắt đầu chỉ nhận được một kết quả duy nhất khi tôi mong đợi ba. Điều này khiến tôi nhìn vào bảng kết hợp/tham gia logic (xem mục thứ hai bên dưới). Chỉnh đoạn mã trong ConfigurationContentsTable:

[Column(Storage = "_configurationContentId", DbType = "BigInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)] 
public long ConfigurationContentId 
{ 
    get { return _configurationContentId; } 
} 

Thứ hai, đối với tất cả các EntityRef <> properties với [Association(Storage = ...] thuộc tính, tôi đã có ThisKeyOtherKey tính đảo ngược. Khi tôi đã thay đổi ConfigurationContentsTable để sử dụng ThisKey và ConfigurationContextsTable và ConfigurationSectionsTable để sử dụng OtherKey, tôi bắt đầu thấy ba kết quả khác biệt dự kiến.

Corrected mã cho ConfigurationContentsTable:

[Association(Storage = "_configurationContextsTable", ThisKey = "ConfigurationContextId")] 
public ConfigurationContextsTable ConfigurationContextsTable 
{ 
    get { return _configurationContextsTable.Entity; } 
    set { _configurationContextsTable.Entity = value; } 
} 

[Association(Storage = "_configurationSectionsTable", ThisKey = "ConfigurationSectionId")] 
public ConfigurationSectionsTable ConfigurationSectionsTable 
{ 
    get { return _configurationSectionsTable.Entity; } 
    set { _configurationSectionsTable.Entity = value; } 
} 

Corrected mã cho ConfigurationContextsTable:

[Association(Storage = "_configurationContentsTable", OtherKey = "ConfigurationContextId")] 
public ConfigurationContentsTable ConfigurationContentsTable 
{ 
    get { return _configurationContentsTable.Entity; } 
    set { _configurationContentsTable.Entity = value; } 
} 

Và cuối cùng, điều chỉnh mã cho ConfigurationSectionsTable:

[Association(Storage = "_configurationContentsTable", OtherKey = "ConfigurationSectionId")] 
public ConfigurationContentsTable ConfigurationContentsTable 
{ 
    get { return _configurationContentsTable.Entity; } 
    set { _configurationContentsTable.Entity = value; } 
} 
+0

Tôi đã gặp phải vấn đề này vì tôi đã tạo các lớp thực thể Linq của mình bằng tay. Tôi đã tránh được vấn đề này hoàn toàn vì tôi chỉ cần thêm một mục "LINQ to SQL Classes" tạo một bề mặt thiết kế dbml mà bạn có thể kéo kết nối cơ sở dữ liệu của bạn (từ trình thám hiểm máy chủ). Làm điều này tự động tạo ra tất cả các lớp thực thể cho bạn. – Sam

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