2011-06-17 125 views
2

我從包含默認列值的現有數據庫生成了我的EDMX。我也有用T4模板生成的POCO對象。實體框架4中默認的SQL Server列值POCO

現在我遇到的情況,我想創建一個POCO並將其保存到這樣的數據庫:

dim tablePocoEntityInstance as New tablePocoEntity 
context.MsSQLTable.AddObject(tablePocoEntityInstance) 
context.SaveChanges() 

這是工作的罰款與在SQL Server數據庫中設置默認值的例外。

例如:

SQL Server表

id (int, not null, auto increament) 
    magicNR (int, not null, defaultValue = 11) 

生成POCO對象有那麼兩個屬性:

Partial Public Class tablePocoEntity 
    Public Overridable Property id As Integer 
    Public Overridable Property magicNR As Integer 
... 

問題是,magicNR不能爲空並獲得隱式初始化。當我保存對象時,id是應該的,但magicNR的值爲0而不是11,這是默認值。

我的問題:

  1. 我可以設置我的實體的方式,他們將使用數據庫的默認列值?
  2. 如果不是我怎樣才能在代碼中設置默認值?
  3. 解決此問題的最佳方法是什麼?

回答

1

我不知道哪種開箱即用的解決方案 - 但由於這些POCO類是使用T4模板從數據庫中生成的,因此您可以隨時修改這些模板以檢查數據庫並找到並尊重列默認值。

在這種情況下,您的對象可能會有一個構造函數將這些列設置爲數據庫定義所定義的默認值。

2

打開您的實體.edmx並右鍵單擊相關數據字段並選擇屬性。在DataBaseScriptGeneration下,將StoreGeneratedPattern更改爲「Computed」。一旦設置完成,您的應用程序將按預期工作 - SQL Server將插入默認值。但是,您將無法從應用程序端強制創建一個值。

0

好吧,這個問題是相當古老,但我仍然想分享我的解決方案。

我所做的是修改T4模板,以便爲所有生成的實體添加一個部分方法,並從構造函數中調用它。 此部分方法是在擴展的部分類中實現的,您將爲每個需要手動創建的實體設置默認值。

注:我使用EF6

短步驟:

1)修改T4模板以包括這樣的部分方法:

partial void OnCreationComplete(); 

2)修改T4模板以在構造函數中調用該方法

OnCreationComplete(); 

3)創建一個部分類OSE,您需要設置一個默認屬性和落實OnCreationComplete方法實體:

partial void OnCreationComplete() 
{ 
    PropertyFoo = "Bar"; 
} 

下面是完整的代碼:

T4模板生成的類

// You might want to remove the IF statement that excludes the constructor generation for entities without collection and complex entities... 
<# 
    var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); 
    var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); 
    var complexProperties = typeMapper.GetComplexProperties(entity); 
#> 
    public <#=code.Escape(entity)#>() 
    { 
<# 
     foreach (var edmProperty in propertiesWithDefaultValues) 
     { 
#> 
     <#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; 
<# 
     } 

     foreach (var navigationProperty in collectionNavigationProperties) 
     { 
#> 
     <#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); 
<# 
     } 

     foreach (var complexProperty in complexProperties) 
     { 
#> 
     <#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); 
<# 
     } 
#> 
     OnCreationComplete(); 
    } 

    partial void OnCreationComplete(); 

例子:

//------------------------------------------------------------------------------ 
// <auto-generated> 
//  This code was generated from a template. 
// 
//  Manual changes to this file may cause unexpected behavior in your application. 
//  Manual changes to this file will be overwritten if the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

namespace MyTest.DAL 
{ 

    using System; 
    using System.Collections.Generic; 
    using System.ComponentModel.DataAnnotations; 

    public partial class Foo 
    { 
     public Foo() 
     { 
      OnCreationComplete(); 
     } 

     partial void OnCreationComplete(); 

     public string MyPropertyFoo { get; set; } 

    } 
} 

擴展部分類

public partial class Foo 
{ 
    partial void OnCreationComplete() 
    { 
     MyPropertyFoo = "Bar"; 
    } 
} 

希望它可以幫助別人......