none
使用有辦法建構出已經Join過後的Entity Data Model嗎? RRS feed

  • 問題

  • 各位前輩大大安,

    很抱歉,小弟想問一個奇怪的問題XD

    小弟有拜讀過許多前輩的文章,也漸漸的了解EDM的用途,

    但小弟有一個疑惑,

    例如現在有一個網頁,要show出,北風資料庫裡面A客戶訂了哪些訂單。

    我們知道北風的Customer和Order是一個一對多的關係,

    以前在處理類似程式的時候,

    可能用SQL直接把這兩個表Join起來,然後再用Where去做條件篩選。

    再把撈出來得資料( 假設已經存到Dataset ) 塞到datagrid裡面。

    那如果是使用EDM的話要怎麼做呢??

    有沒有辦法將Customer和Order直接在EDM設計工具的時候就已經join好,並產生一個物件,

    然後直接用Linq去撈此單一的物件呢??

    還是說,也還是一樣是Customer和Order兩個物件,

    再用Linq Join起來呢?

    目前看到的一些範例,似乎都是對單一Table,

    如果遇到必須要join類似三四個Table以上,或是又要子查詢的SQL

    在使用EDM上,各位大大有什麼樣的建議呢?

    先在此,感謝各位大大對新手的我熱情的指教與糾正,謝謝^^~

    2010年5月2日 下午 02:36

解答

  • 附上程式碼片段:

     

    using NorthwindDemo.Common;
    using System.Data.Objects;
    using System.Collections.Generic;
    using System.Linq;
    
    public class Customers
    {
      public List<Orders> GetCusomterOrders(string CustomerID)
      {
        using (NorthwindEntities context = new NorthwindEntities())
        {
          ObjectQuery<NorthwindDemo.Common.Customers> c = context.Customers;
          ObjectQuery<NorthwindDemo.Common.Orders> o = context.Orders;
          IQueryable<Orders> Result = from p in c
                        join q in o on p.CustomerID equals q.CustomerID
                        where p.CustomerID == CustomerID 
                        select q;
          return Result.ToList<Orders>();              
        }
      }
    }

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using NorthwindDemo.Common;
    
    namespace NorthwindDemo
    {
      public partial class _Default : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          Customers objCustomers = new Customers();
          List<Orders> CustomersOrder = objCustomers.GetCusomterOrders("ALFKI");
          foreach (var order in CustomersOrder)
          {
            Response.Write(string.Format("{0},{1},{2}<br/>", order.CustomerID, order.OrderID, order.OrderDate));
          }
          objCustomers = null;
        }
      }
    }
    

    • 已標示為解答 Sky Chang 2010年5月3日 上午 04:40
    2010年5月3日 上午 01:57
  • 每次回覆EF問題,還是強調一件事,EF不是用來取代ADO.Net,用EF要用OO角度去思考,不要用關聯式資料庫方式去思考.

    你的問題很簡單Customer跟Order在EF會建立兩個的Class.然後這兩個Class會有1對多關係.

    所以Customer class會有個Orders屬性,表示這家客戶底下的所有訂單,反之也可以讓Order class有個Customer屬性,代表這份訂單的客戶為何.

    故程式中就可以使用
    Order.Customer.Name取得客戶名稱.

    另外EF目前僅能算是一個ORM,而你說的問題要Join很多Table該如何處理.這個問題要解決你的架構必須採用OO,使用OO自然就會消失.
    如果程式寫法還是傳統程序式方式,EF其實並不適合,所以建議當真正用OO開始設計架構時,遇到資料存取問題再來評估EF.而不是直接把EF用來取代 ADO.Net這是錯誤的做法.

    • 已標示為解答 Sky Chang 2010年5月3日 上午 04:40
    2010年5月3日 上午 03:50

所有回覆

  • 先在資料庫建立VIEW就行了
    2010年5月2日 下午 03:21
  • 如果你對SQL SERVER比較不熟的話,或許可以考慮建立一個類別,然後在裡面將你要JOIN的TABLE用LINQ所提供的JOIN功能先JOIN起來,然後其他程式再去使用這個共用類別,或許也可以達到你要的功能,不過阿尼的方法可能比較簡單點,以上供您參考,謝謝。
    • 已提議為解答 阿尼 2010年5月3日 上午 02:13
    2010年5月2日 下午 11:14
  • 附上程式碼片段:

     

    using NorthwindDemo.Common;
    using System.Data.Objects;
    using System.Collections.Generic;
    using System.Linq;
    
    public class Customers
    {
      public List<Orders> GetCusomterOrders(string CustomerID)
      {
        using (NorthwindEntities context = new NorthwindEntities())
        {
          ObjectQuery<NorthwindDemo.Common.Customers> c = context.Customers;
          ObjectQuery<NorthwindDemo.Common.Orders> o = context.Orders;
          IQueryable<Orders> Result = from p in c
                        join q in o on p.CustomerID equals q.CustomerID
                        where p.CustomerID == CustomerID 
                        select q;
          return Result.ToList<Orders>();              
        }
      }
    }

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using NorthwindDemo.Common;
    
    namespace NorthwindDemo
    {
      public partial class _Default : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          Customers objCustomers = new Customers();
          List<Orders> CustomersOrder = objCustomers.GetCusomterOrders("ALFKI");
          foreach (var order in CustomersOrder)
          {
            Response.Write(string.Format("{0},{1},{2}<br/>", order.CustomerID, order.OrderID, order.OrderDate));
          }
          objCustomers = null;
        }
      }
    }
    

    • 已標示為解答 Sky Chang 2010年5月3日 上午 04:40
    2010年5月3日 上午 01:57
  • 建立一個類別,然後在裡面將你要JOIN的TABLE用LINQ所提供的JOIN功能先JOIN起來,然後其他程式再去使用這個共用類別

    好方法,讚
    2010年5月3日 上午 02:15
  • 每次回覆EF問題,還是強調一件事,EF不是用來取代ADO.Net,用EF要用OO角度去思考,不要用關聯式資料庫方式去思考.

    你的問題很簡單Customer跟Order在EF會建立兩個的Class.然後這兩個Class會有1對多關係.

    所以Customer class會有個Orders屬性,表示這家客戶底下的所有訂單,反之也可以讓Order class有個Customer屬性,代表這份訂單的客戶為何.

    故程式中就可以使用
    Order.Customer.Name取得客戶名稱.

    另外EF目前僅能算是一個ORM,而你說的問題要Join很多Table該如何處理.這個問題要解決你的架構必須採用OO,使用OO自然就會消失.
    如果程式寫法還是傳統程序式方式,EF其實並不適合,所以建議當真正用OO開始設計架構時,遇到資料存取問題再來評估EF.而不是直接把EF用來取代 ADO.Net這是錯誤的做法.

    • 已標示為解答 Sky Chang 2010年5月3日 上午 04:40
    2010年5月3日 上午 03:50
  • 感謝各位大大的解答,讓小弟更加的了解這方面的知識~^^~。

    也有勞TerryChuang大勞心的貼程式碼,與阿尼大的建議。

    還有如Programlin大大說的觀念,也超貼切的。

    在此,再一次感謝各位大大給小弟我的指教。

    謝謝^^~

    2010年5月3日 上午 04:50