如何使用EF 4.x DbContext生成器获取属性更改通知 [英] How to get property change notifications with EF 4.x DbContext generator

查看:554
本文介绍了如何使用EF 4.x DbContext生成器获取属性更改通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩Entity Framework 4.3,所以我正在使用DbContext Generator创建上下文和实体类。



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



当我使用EF 4.x DbContext生成器时,如下图所示,实体类更轻,而且不包括追踪资产变更的任何方式。





以下是一个示例:

  // -------------------------------------------- ---------------------------------- 
//< auto-generated>
//该代码是从模板生成的。
//
//手动更改此文件可能会导致应用程序出现意外的行为。
//如果重新生成代码,则对该文件的手动更改将被覆盖。
//< / auto-generated>
// -------------------------------------------- ----------------------------------

使用系统;
使用System.Collections.Generic;

命名空间SomeNamespace
{
public partial class SomeTable
{
public SomeTable()
{
this.Children = new的HashSet<儿童>();
}

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

public virtual Parent Parent {get;组; }
public virtual ICollection< Child>孩子{get;组; }
}
}

我一定缺少一个重要的难题,但我的搜索是无效的。所以我的问题是:如何生成类型包括EF 4.3的属性更改通知?



修改



我完全同意@derape答案;但是当EF 4默认代码生成模板已经有钩子时,我很好奇为什么我需要更改 .tt 文件。我的意思是当绑定到WPF DependencyProperty '时呢?没有INotifyPropertyChanged,一个命令对一堆对象中的一组属性所做的更改不会反映在UI中。我缺少什么?

解决方案

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



将以下内容添加到CodeStringGenerator类

  public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
{0} {1}局部类{2} {3}:{4},
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape ),
_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)),
设置{_+ _ code.Escape(edmProperty).ToLower()+= value; OnPropertyChanged(\+ _ code.Escape(edmProperty)+\);},
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());

}

将以下内容添加到生成器

 使用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(simpleProperties中的var edmProperty)
{
#>
<#= codeStringGenerator.Private(edmProperty)#>
<#= codeStringGenerator.Property(edmProperty)#>
<#
}


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


I'm playing around with Entity Framework 4.3, and so I am using the DbContext Generator to create the context and entity classes.

With the default EF 4 code generator template, entity classes implement INotifyPropertyChanged, and also add Changing and Changed partial methods in property setters.

When I use the EF 4.x DbContext generator, as pictured below, the entity classes are much lighter, and do not include any means of tracking property changes.

Here is an example:

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

I must be missing an important piece of the puzzle, but my searches have been fruitless. So my question is: how can I have generated types included property change notifications with EF 4.3?

Edit

I fully agree with @derape answer's; but I am curious as to why I would need to change the .tt file when the EF 4 default code generation template already has the hooks. I mean what about when binding to a WPF DependencyProperty'? Without INotifyPropertyChanged, changes done by a command to a bunch of properties in a bunch of objects won't be reflected in the UI. What am I missing?

解决方案

I recently stumbled upon this problem, i edited my Entity.tt to implement the following changes, a quick patch but works great..

Add the following to the CodeStringGenerator class

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());

}

Add the following to the generator

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));
}

And abit further down

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


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

这篇关于如何使用EF 4.x DbContext生成器获取属性更改通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆