(翻譯)Entity Framework技巧系列之一 – Tip 1 – 5

來源:互聯網
上載者:User

本系列英文原文出自。

提示1. 在Entity Framework中怎樣排序關係(Relationships)

問題:

    在Entity Framework論壇中常會看到關於排序相關聯項目的問題。

    例如,想象你要查詢客戶,並返回那些欠款超過30的賬戶,與此同時檢索這些賬戶的訂單。

    並且你需要將那些訂單按下單日期排序,這樣你可以首先看到最近的訂單,以便輕鬆的尋找到可疑的行為。

答案:

    大部分人們可能都知道EF中可以使用Include()即時載入一個關係。如下樣本:

var lateCustomers = from c in ctx.Customers.Include("Orders")
                    where c.IsMoreThan30DaysInArrears
                    select c;

但不幸的是,這個語句返回的每個客戶的訂單都是無序的。

    所以你怎樣排序這些訂單呢?嚴格地說沒有辦法。

但是你也可以做一些這樣的工作,如在select子句中進行include操作。

var lateCustomers = from c in ctx.Customers
                where c.IsMoreThan30DaysInArrears
                select new { 
                    Customer = c, 
                    Orders = c.Orders.OrderByDescending(
                                 o => o.OrderDate
                             ) 
                }; 

    這個語句使用標準的LINQ語義請求一個由客戶及其排序過的所有訂單組成的匿名型別的迭代。

    Entity Framework可以很好的支援這種寫法所以問題得到解決…

補充知識:

以上做法有幾分…

我沒有使用實體來擷取資料,而是使用了其它東西 – 一個匿名型別。

這種方式不是很理想。

你很想通過customer.Orders屬性來訪問客戶的訂單。有趣的是即使名為Fix-up的東西已經實現了這個目標。

Entity Framework的物件服務會自動將相關聯的事物綁定在一起,這個過程就稱為Fix-up。

一般情況下,Fix-up這個過程發生在兩個相關聯的實體進入內容相關的那一刻。

所以因為我已經載入了Customer與Orders兩者(通過投影),Fix-up也將會保證customer.Orders屬性包含那些訂單。這是我的查詢中沒有使用Include("Orders")的真正原因。

這迴避了問題,從而引出了新問題:Customer.Orders可以被排序嗎?

不幸的是,目前沒有官方解決方式。

這不是我們要支援的特性,我們沒有花時間 – 必要的時間來測試它,確保其可以在每種情境下工作。你知道那都是重要的QA問題。

雖然有反對者,但無論如何這可以工作…

為什麼呢?

我的猜測是在查詢中執行排序,編寫基於DataReader來執行個體化實體並最終進行Fix-up的代碼是有副作用的。

現在,理論上你可以在項目中使用這個特性…但是,注意這是個大大的轉折,請明白這是不推薦的。

依賴於一種有潛在的負面作用的特殊實現總是存在一點風險。

 

提示2. Entity Framework書籍

問題:

在哪可以找到深入學習Entity Framework的書籍?

答案:

在微軟產品小組的產品上做開發的一個好處是可以接觸到想讓你審閱他們書籍的作者。

    到目前為止我收到3位不同的作者發給我的他們的Entity Framework書籍的書稿。

如下是我按收到它們的順序:

 

ADO.NET Entity Framework - Unai Zorrilla Castro / Octavio Hernandez / Eduardo Quintas

這本書是用西班牙語寫的,本質上單一語言的,所以個人很難對其品質進行評論,但是我的阿根廷同事推薦這本書,對我這就足夠好了。儘管如此,我還是喜歡將其放在我的書架上,這讓我看起來很先進…所以謝謝Unai。

 

Programming Entity Framework - Julie Lerman

我與Julie進行過幾次個人會面,我知道她在這本上傾注了她的心血。所以這本將近800頁的書講的如此透徹也就不令人吃驚了。Julie的書中包含了大量有用的資訊以及一些現實中的例子。

Julie,謝謝你的書。

 

Professional ADO.NET 3.5 with LINQ and the Entity Framework - Roger Jennings

我從沒見過Roger,但是從他的部落格上可以明確的知道他使我們感覺可靠。他的書與Julie的書有一點不同,因為其講述了Entitiy Framework周圍其它一些事物,如LINQ to XML,LINQ to DataSet等。我昨天剛收到這本書(謝謝Roger),但是我相信其很有市場。

 

正如在這看到的這些很好選擇…

祝你的Entity Framework順利

 

提示3. 開始T4之旅

    如果你讀過Entity Framework Design Blog,你應該已經聽我們討論過T4。這是一項與Visual Studio 2008一起發行的技術(2005有一個獨立的版本供下載)。

    在.NET4.0中,Entity Framework使用了T4來增強代碼產生與模型初始化這種情境。

事實上T4現在也用在其它一大些微軟的產品,包括ASP.NET MVC和Dynamic Data。

所以考慮如果現在要開始使用T4並開始熟悉這種技術,你應該怎麼做?

事實上這種技術相對簡單。你可以非常輕鬆的完成相當有用的事情:

 

  • 向項目中添加一個文字檔,並將副檔名改為".tt"。
  • 在文字檔中寫入一些模版代碼。

    <#@import namespace="System.Collections.Generic" #>
    <#
    Dictionary<string,Type> properties = new Dictionary<string,Type>();
    properties.Add("Age",typeof(int));
    properties.Add("Firstname", typeof(string));
    properties.Add("Surname", typeof(string));
    #>
    using System;

    public class <#="MyClass"#>{
    <# foreach(string name in properties.Keys) { #>
        public <#=properties[name].Name#> <#=name#>{
            get; set;
        }
    <# } #>
    }

這些模版代碼產生了一個類,並使用了一個名為"properties"的字典的每一個Key作為這個類的屬性。

  • 儲存".tt"檔案。當你完成這一步時,不可思議的會自動出現一個依賴於模版的".cs"檔案,其看來像下面這樣:

    using System;

    public class MyClass{
          public Int32 Age{
                get; set;
          }
          public String Firstname{
                get; set;
          }
          public String Surname{
                get; set;
          }
    }

正如你看到的,T4非常簡單且對熟悉ASP.NET的使用者來說相當容易使用…

試一下吧。

 

提示4. 概念模式定義語言規則

    第一個版本的Entity Framework在不久以前隨著.NET 3.5 SP1一些發布了。

    Entity Framework文檔的一個最大漏洞是缺少一個對CSDL(概念模式描述語言)的正式文檔描述。

人們想瞭解的CSDL是Entity Framework用來描述實體資料模型(EDM)的具體格式。

這些規則可以由嵌入System.Data.Entity.dll程式集資源中的XSD推到而出,但是一大些規則靠Entity Framework本身來限制。

    如果你對這些規則的細節感興趣,可以參見formal CSDL specification here。

    這份文檔主要針對Astoria所使用的CSDL1.1版本,但是CSDL1.0與1.1版本的大部分是相同的,這些差異都明確的列於這裡。

免責聲明:我協助編輯了這個文檔的一些部分。如果你存在問題請告訴我。

 

提示5. 如何限制EF查詢返回的類型

    考慮你有一個如下這樣的模型:

 

怎樣僅僅查詢Cars?

 

這是OfType<SubType>()登場的時候。你編寫如下這樣的代碼:

var onlyCars = from car in ctx.Vehicles.OfType<Car>()
               select car;

且這個可以很好的工作。這將結果限制在Cars,附帶包含了Cars,Sports

怎樣僅查詢Cars而不附帶其子類型?

考慮你的預算只夠選擇一個簡單的家用轎車。這意味著你不想要SUV與運動轎車(SportsCars)。

你需要在查詢中明確限制以避免返回所有的子類型:

var onlyCars = from car in ctx.Vehicles.OfType<Car>()
               where !(car is SportsCar) && !(car is SUV)
               select car;

現在你的代碼僅返回Cars類型的對象。

外傳

這種解決方案唯一令人遺憾的是你不得不顯示排除所有你可能不想要的子類型,在某些有多級繼承或一級中有大量衍生類別的情況下可能會有很多子類。

如果下面的寫法被支援將會更好(可惜這是不支援的):

var onlyCars = from car in ctx.Vehicles.OfType<Car>()
               where car.GetType() == typeof(Car)
               select car;

問題是你認為支援這種類型的查詢對我們有多重要呢?

 

BTW:C#資料結構與演算法系列翻譯停止,原因嗎..此書早已有中文版(詳見)面試,我就不重複造輪子了..

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.