2012-08-27 62 views
1

我正在研究3層應用程序。此外,我正在使用LINQ to SQL進行數據訪問。LINQ連接方法的正確返回值是什麼?

數據層具有返回客戶的表格的函數:

public Table<Customer> getCustomers() 
{ 
    DataContext context = new DataContext(); 
    Table<Customer> customerTable = context.GetTable<Customer>(); 

    return customerTable; 
} 

它提供給業務層,其中結果被傳遞給表示層爲IEnumerable<Customer>

public IEnumerable<Customer> getCustomers() 
{ 
    CustomerDAL customerDAL = new CustomerDAL(); 

    return from c in customerDAL.getCustomers() select c;    
} 

在表示層中,我簡單地使用IEnumerable作爲DatagridView的DataSource。

如果我有另一個表如「信息」和表customerDAL.getInfo()表怎麼辦?現在我想在業務層的方法中進行連接查詢。我想像是這樣的:

public IEnumerable<Customer> getCustomerInfo() 
{ 
    CustomerDAL customerDAL = new CustomerDAL(); 

    return from c in customerDAL.getCustomers() 
        join i in customerDAL.getInfo() on c.id equals i.InfoID 
        select new { c.id, c.Name, i.DateTime, i.Project }; 
} 

問題是IEnumerable需要對象的類型。我的返回值不再是客戶表,而是客戶表和信息表的組合。我是否正確?這裏的返回值是正確的選擇?

你的建議後,我創建了一個自定義類,CustomerInfo.cs

public class CustomerInfo 
    {   
     string name { get; set; } 
     long id { get; set; } 
     string dateTime { get; set; } 
     string project { get; set; } 


     public CustomerInfo(long _id, string _name, string _date, string _project) 
     { 
      name = _name; 
      id = _id; 
      dateTime = _date; 
      project = _project; 
     } 
    } 

然後我打電話完全一樣的方法,由Reed描述。但是,當我設置DataSource的表示層中我得到異常:

The query contains references to items defined on a different data context. 

其實這是不正確的所有實體類是在同一個.dbml文件。什麼可能是錯的?

回答

1

關於第二錯誤:

然後如由Reed描述我打電話完全相同的方法。但是在Presentation-Layer中,當我設置DataSource時,我得到以下異常: 查詢包含對在不同數據上下文中定義的項目的引用。

很可能您的DAL正在爲您要返回的每個表實例化一個單獨的上下文實例(在ActiveRecord模式實現中是典型的)。爲了使連接起作用,兩個表都需要由相同的上下文對象來檢索。您可能需要修改DAL,以便在DAL的構造函數中注入上下文,以便您可以集中上下文的生命週期。

0

到目前爲止,一切都看起來不錯。如果你想在單個方法的範圍內使用查詢,那麼使用匿名類(這就是你現在正在做的)就好了。既然你不是,你需要爲你的投影創建一個具體的類,以便你可以返回它。

查詢將變成:

select new SomeClassYouAreAboutToCreate { c.id, c.Name, i.DateTime, i.Project }; 

那類可以或許只是有一堆性質,idName等你只是在設置這些屬性在Select的。

+0

這是否意味着我正在用IEnumerables填充的自定義類上運行LINQ查詢,並且可以使用返回值作爲DataSource? – Prot

1

What would be the right choice for a return value here?

如果你想返回一個強類型的類,您將需要一個自定義的類來表示這種類型的,如CustomerInfo類。你需要定義這個類,並且包含適當的屬性和構造函數。你可以這樣做:

public IEnumerable<CustomerInfo> GetCustomerInfo() 
{ 
     CustomerDAL customerDAL = new CustomerDAL(); 

     return from c in customerDAL.getCustomers() 
        join i in customerDAL.getInfo() on c.id equals i.InfoID 
        select new CustomerInfo(c.id, c.Name, i.DateTime, i.Project); 
} 

這將允許你以強類型的方式返回你需要的確切信息。我認爲在這種情況下創建自定義類尤其重要,因爲您將其定義爲公共API的一部分。

+0

這是否意味着我正在用IEnumerables填充的自定義類上運行LINQ查詢,並且可以使用返回值作爲DataSource? – Prot

+0

@Prot否 - 當然,您可以使用LINQ to Objects來過濾結果,但它不會是一個針對數據庫的數據源。 –

0

當你創建一個這樣的匿名對象時,它的類型是dynamic。所以返回匿名對象的列表那樣,你可以使用下面的簽名:

public IEnumerable<dynamic> getCustomerInfo() { 
    CustomerDAL customerDAL = new CustomerDAL(); 

    return from c in customerDAL.getCustomers() 
     join i in customerDAL.getInfo() on c.id equals i.InfoID 
     select new { c.id, c.Name, i.DateTime, i.Project }; 
} 

請記住,雖然,dynamic類型都有其缺點。特別是,你失去了強大的打字,這可能會導致難以找到的錯誤。您應該考慮Servy's answer以獲得更強大的解決方案。

+0

該dype不是動態的。它是匿名的強類型。 – usr

相關問題