c# - EF 4.3 和 POCO 类 - 在哪里拦截属性值?

标签 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 以始终将其设置为大写。例如这样:

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:默认

再次生成 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();
    }
}

问候。

最佳答案

生成的实体类是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
}

编辑: Entity Framework 使用公共(public)属性中的私有(private)字段来保存值。它们通常被命名为 _<property name> - 检查您生成的代码以查看其使用的内容。因此,将 FullName 大写的代码如下所示:

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

关于c# - EF 4.3 和 POCO 类 - 在哪里拦截属性值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9568878/

相关文章:

c# - 检测应用于 IQueryable<T> 的位置

c# - Entity Framework 在查询中创建一个不存在的列

c# - Entity Framework 中的 POCO 支持

domain-driven-design - DDD、存储库和封装

C# 如何在转换 ToString() 之前检查是否有任何值

c# - 获取两个值之间的时间差

c# - EF Core/Sqlite 一对多关系因唯一索引约束而失败

database - Access 2007 - 2010 可以使用什么 ORM?我在 WPF 绑定(bind)到表等之后

c# - Microsoft.AspNet.Identity.EntityFramework.IdentityUser 的外键?

c# - Windows 窗体 - 如何在 C# 的组合框项目中添加不可选的标题?