2011-06-17 122 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"; 
    } 
} 

希望它可以帮助别人......