EF 4.3和POCO类 - 拦截属性值?

时间:2012-03-05 15:06:09

标签: c# entity-framework poco

我开始了解并使用Entity Framework。我正在尝试做一些简单的尖峰来了解它是如何工作的。

我的第一个问题是从客户端UI截取值并在保留它们之前更改它的正确方法是什么。

在示例中,我们有EF 4.x DbContext Generator模板自动生成的此Person模型:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace EFModelDatabaseFirst
{
    public partial class Person
    {
        #region Primitive Properties        
        public virtual int Id { get; set; }        
        public virtual string FullName { get; set; }       
        public virtual string LastName { get; set; }
        #endregion
    }
}

我想将FullName setter修改为始终在UpperCase中设置它。例如,以这种方式:

public partial class Person
{
    private string fullname;

    #region Primitive Properties        
    public virtual int Id { get; set; }        
    public virtual string FullName { 
        get { return fullname; } 
        set { fullname = value.ToUpper(); }       
    public virtual string LastName { get; set; }
    #endregion
}

但是我必须继续研究模型,当我从修改后的模型中再次执行“添加代码生成项...”时,当模板重写所有文件时,我的所有手写修改都将丢失。

实施此方法的最佳方法是什么?

感谢。

修改

===来自@Codeulike的答案===

如果我尝试以这种方式创建一个分部类:

public partial class Person
{
    partial void OnFullNameChanging(string value)
    {
        this.FullName = value.ToUpper();
    }
}

然后我有一个无限循环,所以有一个stackoverflow异常。我必须删除POCO类并使用model.edmx激活Code Generation Strategy:默认

再次生成POCO类并尝试以另一种方式创建分部类:

public partial class Person
{
    private string fullname;

    partial string FullName
    {
        get
        {
            return fullname;
        }
        set
        {
            fullname = value.ToUpper();
        }
    }
}

编译器给出了一个错误,因为Class Person已经包含'FullName'的定义。

让它运行正常的唯一方法是删除POCO Class Person上的属性。但如果我再次重新生成POCO类,则所有更改都将丢失。

修改

===来自@Codeulike + @Guvante的回答===

最后我以这种方式创建了一个部分类:

public partial class Person
{
    partial void OnFullNameChanging(string value)
    {
        // _FullName is the backend field EF generates.
        this._FullName = value.ToUpper();
    }
}

但是这不会运行,并且FullName值(在数据库上)不会更改为UpperCase。我必须以另一种方式做,它运行良好:

public partial class Person
{
    partial void OnFullNameChanged()
    {
        this._FullName = this.FullName.ToUpper();
    }
}

问候。

1 个答案:

答案 0 :(得分:0)

生成的实体类为Partial classes

您可以在单独的.cs文件中创建您的位,它们将全部编译在一起。这使您可以添加内容而不会被代码生成器覆盖。

有关详细信息,请参阅here

编辑:好的,我看到你的getter和setter的问题。显然这是做到这一点的方法:

如何:在标量属性更改期间执行业务逻辑
http://msdn.microsoft.com/en-us/library/cc716747.aspx

您可以为每个属性编写一些部分方法来编写代码。您只需在部分类中实现适当的部分方法,它就会被调用。

e.g。

partial void OnFullNameChanged()
{
    // this partial method gets called when the FullName property has changed
}

编辑:实体框架使用公共属性中的私有字段来保存值。它们通常命名为_<property name> - 检查生成的代码以查看其使用的内容。因此,将FullName大写的代码看起来像是:

partial void OnFullNameChanged()
{
    _FullName = _FullName.ToUpper();
}