轉:使用LINQ聯集查詢多表結果集的返回

來源:互聯網
上載者:User

來自:http://www.yaosansi.com/post/1388.html

首先,我們先來瞭解一些知識點。

1.匿名型別的傳遞

       static void Main(string[] args)
        {
            var User = GetAnonymous().Cast(new { UserName = "", LastLoginIp = "" });
            Console.Write(User.UserName);   
        }
 
        static object GetAnonymous()
        {
            var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" };
            return User;
        }

當我們定義一個匿名型別,只能通過object類型傳遞,傳遞後編譯器將無法獲悉匿名型別的實際類型。

這行可以通過Cast擴充方法來進行強制轉換。以下是Cast方法的原型。

        public static T Cast<T>(this object o, T t)
        {
            return (T)o;
        }
 
2.如何產生匿名型別的List?
 
           var User = GetAnonymous().Cast(new { UserName = "", LastLoginIp = "" });  
           var list = new List<???>();
 原理和上面一致。
            var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" };
            var list = User.MakeList();
            list.Add(User);
            Console.Write(list[0].UserName);

我們再來看看MakeList()方法:

        public static List<T> MakeList<T>(this T t)
        {
            return new List<T>();
        }
 
當然,你可能想到上面的方法還不夠完美,需要在List中Add一個User,於是有了下面的方法:
        public static List<T> MakeList<T>(this T t,params T[] items)
        {
            return new List<T>(items);
        } 
這時調用的時候可以寫成:
            var User = new { UserName = "yaosansi", LastLoginIp = "127.0.0.1" };
            var list = User.MakeList(User);
            Console.Write(list[0].UserName);

這回我們切入正題,來瞭解一下LINQ中是怎樣多表查詢的。

    var q =
    from p in db.Products
    where p.Supplier.Country == "USA" && p.UnitsInStock == 0
    select p;
 
更多內容,請參考:部落格園 - 李永京- LINQ體驗(6)——LINQ to SQL語句之Join和Order By
 
以上的查詢是兩個有關係的表,並且返回的只是一個表的內容,
這種情況下可以在資料層中返回強型別的List。如:
 
 public List<Products> SelectProducts()
 {
      var q =
      from p in db.Products
      where p.Supplier.Country == "USA" && p.UnitsInStock == 0
      select p;
      return q.ToList<Products>;
 }

 
如果返回的結果集是兩個以上表的時候,那該如何傳遞呢?
 
聰明的你一定想到了,如果返回的是單行資料的結果集就可以我們前面提到的 
使用 匿名型別的傳遞 得到我們需要的結果.
 public object SelectProducts()
 {
      var q =
      from p in db.Products
      where p.Supplier.Country == "USA" && p.UnitsInStock == 0
      select new {p.UnitsInStock,p.Supplier.Sid};
      var result = q.Single();
      return result;
 }
但這個前提是商務邏輯層需要知道資料層的匿名型別中的具體類型。
這樣分層的意義也就不大了。這並不是我們想要的。
而且返回多行資料的結果集時用 匿名的List類型 的方法經實驗也失敗了。
這就意味著本文開篇的兩種傳遞匿名型別的方法都行不通。
 
方法一:
自訂與傳回型別相同結構的類,
        public class CustomQuery
        {
            public uint UnitsInStock { get; set; }
            public int Sid { get; set; }
        }
這樣在查詢結果為多個表的結果集時,就可以解決了。
由於需要知道返回的匿名型別,除了不符合多層以外,還需要額外定義一個類。
但這樣確時可以使用強型別返回我們所需要的結果。
 
方法二:
使用System.Func委託 (參考:Returning var from a method in C# 3.0)
 
資料層:
public IEnumerable<TProjection> GetCustomersWithOrders<TProjection>(Func<Customer, IEnumerable<Order>, TProjection> projection) {
    return from customer in _customers
           let customerOrders = from order in _orders
                                where order.CustomerID = customer.ID
           select projection(customer, customerOrders);
}
 
商務邏輯層:
var results = GetCustomersWithOrders((customer, orders) =>
 new {
                 Name = customer.Name,
                 OrderCount = orders.Count()
      });

這樣返回的結果在商務邏輯層裡仍然是真正的匿名型別,可以直接使用了。

方法三:

使用預存程序或視圖。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.