2011-12-20 52 views
1

在EF中使用「ADO.NET EntityObject生成器」的有效原因是什麼?如果你不知道,它會生成一個T4文件,用於構建edmx中的實體。然後可以更改T4文件以更改實體的生成方式。爲什麼使用T4來修改EF中的實體?

我的問題是:除了更改派生實體(也實現接口)的基類以及更改實體和/或上下文對象和命名約定的可訪問性以外,這有什麼用?考慮EF和部分類的現有特徵。

我拿出2

  1. 抓住從數據庫中的表/列描述和填充的實體和屬性
  2. 摘要產生光wieght DTO的和做汽車的映射。

1似乎有太多的工作,認爲它只是更新的型號的意見,而不是EDMX本身(儘管它可以這樣做)

2這甚至有用嗎?

回答

4

我們用T4模板做了幾件事情。第一個是將生成的代碼拆分爲每個文件一個類,而不是一個大文件。這只是使瀏覽和瀏覽實體更容易。

第二個也是更重要的一個是自動生成數據註釋驗證屬性,如StringLength和Required。這讓我們用單個函數調用來驗證實體,並確保它們的驗證屬性始終與數據庫同步(因爲如果我們更改了DB中的列長度,例如,那麼生成的StringLength()屬性就是當我們做'從數據庫更新模型'時更新)。

在之前的工作中,我們還向實體添加了基類和接口,就像您在問題中提到的一樣。


這是我們從T4模板代碼,可檢查所需的列和字符串的長度,並增加了必要的驗證屬性:嗯

''' <summary> 
    ''' <#=SummaryComment(primitiveProperty)#> 
    ''' </summary><#=LongDescriptionCommentElement(primitiveProperty, 1)#> 
    <EdmScalarPropertyAttribute(EntityKeyProperty:=<#=code.CreateLiteral(ef.IsKey(primitiveProperty))#>, IsNullable:=<#=code.CreateLiteral(ef.IsNullable(primitiveProperty))#>)> 
    <DataMemberAttribute()> 
<#+ 
    ' begin required attribute 
    If Not ef.IsNullable(primitiveProperty) and not ef.IsKey(primitiveProperty) then 
#> 
<#+ 
    If ef.ClrType(primitiveProperty.TypeUsage) = GetType(Guid) Then 
#> 
    <GuidRequiredAttribute(ErrorMessage:="<#=FixName(code.Escape(primitiveProperty))#> is required")> 
<#+ 
    Else 
#> 
    <RequiredAttribute(ErrorMessage:="<#=FixName(code.Escape(primitiveProperty))#> is required")> 
<#+ 
    End If 
#> 
<#+ 
    End If 
    If HasMaxLength(primitiveProperty.TypeUsage) then 
    Dim d = MaxLength(primitiveProperty.TypeUsage) 
#> 
    <StringLengthAttribute(<#=d#>, ErrorMessage:="<#=FixName(code.Escape(primitiveProperty))#> cannot be longer than <#=d#> characters")> 
<#+ 
    End If 
#> 
+0

你如何確定它是否「需要」或允許的最大字符串長度是多少?從EntityType? – ILovePaperTowels 2011-12-20 23:35:23

+0

看我的編輯一些示例代碼。我們從WritePrimitiveTypeProperty方法中的EdmProperty對象讀取IsNullable。我們還有一些額外的幫助方法來確定一個字符串字段是否具有最大長度(上面代碼中的HasMaxLength和MaxLength)。 – 2011-12-20 23:42:00

+0

厚顏無恥而爲死靈道歉,但你不會有那些幫手功能在任何地方在線上網? :) – 2017-12-19 10:58:02

1

,其原因是,你可以用它做任何事情。那麼,爲什麼沒有呢?當然T4的使用對於一些特殊情況非常有限,大多數情況下使用T4是沒有意義的。另一方面,你可以用它做些時髦的事情。例如,你可以定義一些用戶定義的東西。假設您的表格中有一個Sort列。然後你可以定義一個查詢函數,如果這個列存在,它會自動對每個條目進行排序。對於一個例子來說,這可能太微不足道了,但是有很多其他奇怪的體系結構,它們更有意義。

你也可以使用其他代碼生成的東西,沒有EF。所以它的確是完整性和可擴展性。

1

T4模板替換EFv1中使用的自定義工具以生成文件後面的代碼(包含所有類的.designer.cs文件)。 T4的主要優點是你可以通過修改文本.tt文件來改變每個項目。在定製工具更改的情況下大多不可能。

使用T4,您可以完全控制從EDMX生成的實體類。它是EDMX到C#或VB的轉換。NET文件。默認模板創建具有大多數開發人員所需功能的類文件,但如果您需要其他任何東西,則可以簡單地轉到.tt文件並添加它。

可能性的變化是無限的,因爲EDMX文件本身是可擴展的。在EDMX後面只是XML文件,您可以在此文件中包含您自己的自定義XML元素(它有一些限制,但有可能 - here是模型優先方法中SQL生成的一些示例)。一旦在EDMX中有自定義元素,您可以在T4模板中使用它們作爲您想要包含在生成代碼中的附加功能的決策邏輯。實體設計器也是可擴展的 - 您可以創建自定義擴展,將其作爲自定義元素存儲在EDMX文件中。 EDMX和實體設計器擴展在書籍Entity Framework in Action中有很好的描述。

1

我知道這是一個老問題,但我也喜歡碰到過這樣的信息時,我開始了。 在我們的例子中,我們的多層解決方案中有一個win32 Delphi客戶端,我使用了模板(使用C#)來生成.Net中的DTO類以及win32對應模塊。
這允許我們使用在很大程度上自動生成的Delphi代碼封裝在客戶端上的CRUD功能:

procedure Delete; 
class function DeleteDto(const _dESPATCHID: integer) : boolean; 
class function GetNextID : integer; 
class function Get(const _dESPATCHID: integer) : TDtoDESPATCH; overload;  
class function Collection(const __filterXml: string): TList<TDtoDESPATCH>; 
function Load: boolean; overload; 
function Populate(_primaryDict : TDictionary<string, Variant>) : boolean; 
function Save : boolean; overload; 


變化從客戶跟蹤,也可以自動的,所以每個屬性setter將迎來更改的屬性,以確保只更改更改的屬性。 例如:

procedure TDtoDESPATCH.SetSCT_STATUS(const value : string); 
begin 
    if (self.IsLoaded) and (inherited SCT_STATUS <> value) then 
     begin 
     TrackChange('SCT_STATUS'); 
     self.Modified:= True; 
     end; 
    inherited SCT_STATUS := value; 
end; 


在服務器端,另一個模板負責所有CRUD操作中這也是公開爲ASMX Web服務自動生成的WCF服務。接口,WCF方法和所有註釋都是從模板生成的。

// convert to entity 
var _entity = _dto.ToEntity(); 
if(exists) 
{ 
    Global.LogActivity(string.Format("{0} - profile {1}, updating DESPATCH: {2}", racID, profile, _dto.ChangedProperties)); 
    // Attach the entity to the db 
    db.DESPATCHes.Attach(_entity); 
    // Change tracking 
    ChangeTracking<DESPATCH>(_dto.ModifiedProperties, db, _entity); 
} 


在WIN32有可能成爲解決方案的一部分的情況下,手動編碼這一切都將是一個(差)的噩夢。

0

我用他們頗有幾分生成代碼,在一個數據層的水平是對我們有用。

改變他們是否實現額外的合同(接口),添加方法,註釋和非分層應用的情況下(不推薦超出了)添加屬性更改通知。

通過在數據層添加一些這些項目的產生,我已經能夠使用模板示範項目產生在這個級別的鍋爐板代碼了。

底線,如果你可以放心地讓電腦爲你的代碼,那麼它也值得。在我們的案例中,80%的基礎管道工作可以通過代碼生成 - 如果不正確,修復和再生通常非常容易。