2011-04-10 67 views
18

我正在使用實體框架4.我正在使用數據庫的第一個模型,這意味着我從數據庫生成EDM。現在我想添加一些模型定義的函數。我的問題是......在哪裏?實體框架:我在哪裏擴展CSDL/MSL?

如果我把它們放在.edmx文件,不會所有的添加都被我下次更新數據庫,並生成新的EDM打一頓?我的意思是它在.Designer.cs文件的頂部顯示它,「如果代碼重新生成,手動更改此文件將被覆蓋。」

那麼,我在什麼文件中添加了我的內容?

回答

33

我會把它有點深,因爲模型定義的函數不是很出名。

模型定義的函數必須手動添加到EDMX文件的CSDL一部分。您必須以XML格式打開文件並添加一個函數。例如,此型號定義的功能能夠生成員工的全名:

<Function Name="FullName" ReturnType="Edm.String"> 
    <Parameter Name="emp" Type="TestModel.Employee" /> 
    <DefiningExpression> 
    Trim(emp.FirstName) + " " + Trim(emp.LastName) 
    </DefiningExpression> 
</Function> 

現在您可以保存您的EDMX並返回給設計人員。該功能將仍然存在,但在Model瀏覽器中不可見。您可以從數據庫更新模型或刪除所有實體,但功能仍將定義。 EF不刪除EDMX的CSDL部分中的自定義修改。

現在你需要定義.NET功能能夠使用這個模型定義的函數。你可以在任何地方做到。一種方法是使用部分類的上下文,但在同一時間,你可以只使用一些cutom類:

public static class EdmFunctions 
{ 
    [EdmFunction("TestModel", "FullName")] 
    public static string FullName(Employee e) 
    { 
     throw new NotSupportedException("This function is only for L2E query."); 
    } 
} 

你就完成了。剩下的唯一任務是在LINQ到實體查詢中使用的功能:

using (var context = new TestEntities()) 
{ 
    var query = from e in context.Employees 
       select new 
        { 
         e.Id, 
         FullName = EdmFunctions.FullName(e) 
        }; 
    var data = query.ToList(); 
    ... 
} 

模型中定義的功能只是一些可重複使用的實體SQL被轉換爲SQL,使他們能夠在LINQ到實體的查詢只用於。模型定義的函數可能要複雜得多。

+2

偉大的答案 - 很好的知道模型定義的功能不會被破壞,當你更新模型 – BrokenGlass 2011-04-10 18:04:50

+2

作爲後續,還有一個MSDN文章,以及:[如何:在概念模型中定義自定義函數(實體框架)](http://msdn.microsoft.com/en-us/library/dd456812.aspx) – 2012-05-16 19:10:54

+0

喬爾穆勒的另一個問題的答案是類似於你所提到的 - 這是非常徹底的,也展示瞭如何做到這一點LINQ到對象: [LINQ to Entities不能識別方法的'Double Parse(System.String) 1]:http://stackoverflow.com/a/5971677/35133 – 2013-05-21 21:50:04