实体框架4 POCO中的默认SQL Server列值

时间:2011-06-17 10:32:19

标签: .net database entity-framework poco

我从包含默认列值的现有数据库生成了我的EDMX。我还用T4模板生成了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. 处理这个问题的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

打开您的实体.edmx并右键单击相关数据字段并选择属性。在DataBaseScriptGeneration下,将StoreGeneratedPattern更改为“Computed”。一旦设置,您的应用程序将按预期工作 - SQL Server插入默认值。但是,您将无法从应用程序端强制执行值。

答案 1 :(得分:1)

没有我想知道的开箱即用的解决方案 - 但由于这些POCO类是使用T4模板从数据库生成的,因此您可以随时修改这些模板以检查数据库并查找和荣誉列默认值。

在这种情况下,您的对象可能有一个构造函数,可以将这些列设置为数据库定义定义的默认值。

答案 2 :(得分:0)

好的,这个问题已经很久了,但我仍然希望与大家分享我的解决方案。

我所做的是修改T4模板,以便为所有生成的实体添加部分方法,并从构造函数中调用它。 此部分方法在扩展的分部类中实现,您将为需要设置默认值的每个实体手动创建。

注意:我使用的是EF6

简短步骤:

1)修改T4模板以包含这样的部分方法:

partial void OnCreationComplete();

2)修改T4模板以在构造函数

中调用该方法
OnCreationComplete();

3)为那些需要设置默认属性并实现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";
    }
}

希望它有所帮助...