c# - 如何使用 EF 4.x DbContext 生成器获取属性更改通知

标签 c# .net entity-framework inotifypropertychanged

我正在使用 Entity Framework 4.3,因此我使用 DbContext Generator 来创建上下文和实体类。

使用默认的 EF 4 代码生成器模板,实体类实现 INotifyPropertyChanged,并在属性 setter 中添加 ChangingChanged 分部方法。

当我使用 EF 4.x DbContext 生成器时,如下图所示,实体类要轻得多,并且不包括任何跟踪属性更改的方法。

enter image description here

这是一个例子:

//------------------------------------------------------------------------------
// <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>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;

namespace SomeNamespace
{
    public partial class SomeTable
    {
        public SomeTable()
        {
            this.Children = new HashSet<Child>();
        }

        public long parent_id { get; set; }
        public long id { get; set; }
        public string filename { get; set; }
        public byte[] file_blob { get; set; }

        public virtual Parent Parent { get; set; }
        public virtual ICollection<Child> Children { get; set; }
    }
}

我一定错过了一个重要的拼图,但我的搜索没有结果。所以我的问题是:如何使用 EF 4.3 生成包含属性更改通知的类型?

编辑

我完全同意@derape 的回答;但我很好奇为什么当 EF 4 默认代码生成模板已经 有钩子(Hook)时我需要更改 .tt 文件。我的意思是当绑定(bind)到 WPF DependencyProperty 时怎么办?如果没有 INotifyPropertyChanged,通过命令对一堆对象中的一堆属性所做的更改将不会反射(reflect)在 UI 中。我错过了什么?

最佳答案

我最近偶然发现了这个问题,我编辑了我的 Entity.tt 以实现以下更改,这是一个快速补丁,但效果很好..

将以下内容添加到 CodeStringGenerator 类

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3} : {4}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),
        "INotifyPropertyChanged");
}


public string Property(EdmProperty edmProperty)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} {2} {{ {3}{6} {4}{5} }}",
        Accessibility.ForProperty(edmProperty),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)),
        "set { _"+_code.Escape(edmProperty).ToLower()+" = value; OnPropertyChanged(\""+_code.Escape(edmProperty)+"\");}",
        "get { return _"+_code.Escape(edmProperty).ToLower()+"; }");

}
public string Private(EdmProperty edmProperty) {
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} _{2};",
        "private",
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty).ToLower());

}

将以下内容添加到生成器

using System.ComponentModel;
<#=codeStringGenerator.EntityClassOpening(entity)#>
{
<#
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
var complexProperties = typeMapper.GetComplexProperties(entity);
#>

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}

再往下一点

foreach (var edmProperty in simpleProperties)
{
#>
<#=codeStringGenerator.Private(edmProperty)#>
    <#=codeStringGenerator.Property(edmProperty)#>
<#
}


foreach(var complexProperty in complexProperties)
{
#>
<#=codeStringGenerator.Private(complexProperty)#>
    <#=codeStringGenerator.Property(complexProperty)#>
<#
}

关于c# - 如何使用 EF 4.x DbContext 生成器获取属性更改通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11010718/

相关文章:

c# - 仅显示来自 ApplicationException 的消息

.net - 单元测试 Entity Framework

c# - EF Core 迁移不会获取所有属性

c# - 以编程方式选择用于 DirectX 渲染的最佳显卡

c# - WPF 通过界面集合在设计器中显示虚假数据

.net - 垃圾收集器的意义何在

c# - .NET Extension Objects with XSLT——如何遍历一个集合?

c# - 哪个命名空间保存有关 SQL Server TinyInt 数据类型的信息?

c# - 允许编辑一列但不允许编辑另一列

c# - 获取 Windows 应用程序和 ASP.NET 应用程序的应用程序路径的统一方法