【问题标题】:EF 4.3 and POCO Classes - Where intercept property value?EF 4.3 和 POCO 类 - 在哪里截取属性值?
【发布时间】:2012-03-05 15:06:08
【问题描述】:

我开始了解和使用实体框架。我正在尝试做一些简单的尖峰来了解它是如何工作的。

我的第一个问题是从客户端 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 设置器修改为 始终 将其设置为大写。比如这样:

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 类并使用Code Generation Strategy 激活model.edmx:默认

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

public partial class Person
{
    private string fullname;

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

编译器给了我一个错误,因为类 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 值(在数据库上)没有更改为大写。我不得不以另一种方式这样做,并且运行良好:

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

问候。

【问题讨论】:

  • 他正在做一些简单的钉鞋,这是他的第一个家伙。
  • 如果我必须把我所有的家伙都写在这里,StackOverflow 没有足够的空间来保存所有这些。但我认为如果@bzlm 没有任何抱怨,我们可以从这个简单的“第一个”开始。 :-)
  • 我从未听说过在这种情况下使用“dude”。我认为“尖峰”是 XP 术语? @codeulike
  • 是的,spike 是 XP 术语。老兄=怀疑。对不起,这种奇怪的表达方式。
  • (@bzlm whispers 我不知道他在说什么) 编辑:啊,现在他已经解码了:)

标签: c# entity-framework poco


【解决方案1】:

生成的实体类为Partial classes

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

更多详情请参阅here

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

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

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

例如

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

edit:实体框架使用公共属性中的私有字段来保存值。它们通常被命名为_&lt;property name&gt; - 检查您生成的代码以查看它的用途。因此,将 FullName 大写的代码如下所示:

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

【讨论】:

  • 如果我用我的修改创建了一个部分类(即:与 setter value.ToUpper() 相同的属性)。然后我必须手动删除 POCO 类上具有相同名称的属性以避免编译器错误。有没有其他办法?
  • 啊,我明白了。已修改答案。
  • 您不应使用该属性来更改OnFullNameChanged 中的值,而应使用支持值(在他的一个示例中为fullname)。
  • @Guvante - 问题是,我认为实体框架生成代码时没有支持值。
  • @FerPt: OnFullNameChanged 正在被某个东西调用,调用的是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多