Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 激活实体框架5返回的POCOs中INotifyPropertyChanged的推荐做法_C#_Entity Framework_Entity Framework 5 - Fatal编程技术网

C# 激活实体框架5返回的POCOs中INotifyPropertyChanged的推荐做法

C# 激活实体框架5返回的POCOs中INotifyPropertyChanged的推荐做法,c#,entity-framework,entity-framework-5,C#,Entity Framework,Entity Framework 5,我有一些POCO继承自实现INotifyPropertyChanged的公共业务基类。 我还在DAL使用EF5。如果我要对单个竞争对手对象执行提取,如下所示: public ICompetitorCard Fetch(long id) { return this.Fetch<ContactCardContext, ICompetitorCard>( () => { return ContactCardCont

我有一些POCO继承自实现INotifyPropertyChanged的公共业务基类。 我还在DAL使用EF5。如果我要对单个竞争对手对象执行提取,如下所示:

public ICompetitorCard Fetch(long id)
        {
            return this.Fetch<ContactCardContext, ICompetitorCard>(
               () => { return ContactCardContext.GetInstance(this); },
               ctx =>
               {
                   var query = from competitor in ctx.Competitors
                               where competitor.Id == id
                               select competitor;

                   return query.SingleOrDefault();
               }, "ICompetitorCard Fetch(long id) failed");
        }
这样之后,财产通知就会发生火灾。我想我可以这样做:

ICompetitorCard card = query.SingleOrDefault();
if (card!=null){card.IsInitialised = true;}
return card;

但这似乎过于冗长,破坏了封装,对集合等来说是一件痛苦的事情。因此,对于那些处理自己的INotifyPropertyChanged实现的人来说,他们如何使用EF5来管理它?

通常,用于实体框架的poco类型不会实现INotifyPropertyChanged,您需要将所需属性的值映射到一个新类型,然后该类型将绑定到视图(该视图确实实现了INotifyPropertyChanged)。。。根据您的体系结构,它可能是业务对象,甚至可能是视图模型

这在许多情况下都很有用,尤其是当您的数据库很少能够完美地表示您的UI时。

您可以通过订阅对象内的事件来“激活”
INotifyPropertyChanged
,并且在对象实例化之前无法完成此操作

在对象中,除非有订户,否则不会引发更改事件

有关更多信息,请参阅


更新:

您可以订阅
ObjectContext
ObjectMaterialized
事件,将对象标记为已加载。大概是这样的:

((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += 
this.ObjectContext_OnObjectMaterialized;
履行你的职责

ObjectContext_OnObjectMaterialized(object sender, ObjectMaterializedEventArgs e).

EventArgs
将为您提供刚刚实现的对象。

如果它是一个派生,那么可以公平地说它不是POCO吗?:)@梅里奥恩霍斯很公平。我想到了人们“似乎”使用的关于这个主题的搜索词。我想知道是否从“加载DAL”方面处理这个问题比将这个逻辑添加到数据对象中更好。i、 e.停用绑定/事件侦听器。毕竟,这不是一个数据问题。我认为
isinitialized
是一个外部因素,而不是对象是否instantiated@MeirionHughesIsInitialized将是对象的私有字段。仅实例化就足够了,因为“假定”EF使用默认()构造函数实例化对象,然后加载其属性。因此,就我而言,初始化将是(实例化+加载)。。。。一旦完成,对象就可以开始跟踪它自己的状态+触发事件/验证/等等。我不希望对象是dirty=true或state=modified,因为它是从数据库加载的。在这种情况下,State=Unchanged或IsDirty=false;这是一个伟大的观点,但在这种情况下,竞争对手卡是一个近乎完美的匹配。我本可以把这个问题与手头的问题紧密地联系起来。我想我更感兴趣的是知道你是如何知道EF已经完成了加载你的对象的…而没有像上面那样进行中间引用。目前它非常匹配,但数据库发生了变化,你也失去了能够进行投影的优势,只要求你需要的信息。。。我也不明白。。。您遇到的问题只是因为您试图在DTO上实现INotifyPropertyChanged。。。您知道EF已完成加载您的类,因为它返回时已完全加载。。。然后,您通常会将所需的属性映射到新类型(这将通知更改)。我还缺什么?好吧,你说得对。我承认这是一个构思拙劣/懒惰的架构。所以撇开InotifyProperty不谈,我仍然想知道我们如何知道EF是“完成”了它的事情。当类型返回给您时它就完成了。。。如果您请求数据库中的记录。。当表示该记录的poco从查询返回给您时。。。完成了。我不知道您还想要什么?好吧,假设我有一个业务对象,在属性更改时需要业务规则验证。这种变化可以通过与其他业务对象(而不仅仅是UI)的交互来实现。因此,某些业务对象需要在属性更改时运行业务规则,但如果从DB加载对象,则运行规则是浪费。它会在持久化之前被验证,所以我们可以假设它是有效的。因此,我不想在从DB/EF加载后触发验证,但一旦对象加载了数据,我就想在其生命周期的剩余时间内启用验证。是的,我犯的错误是将问题与INotifyPropertyChanged捆绑在一起,这引起了围绕绑定角度的讨论。所以如果我在跟踪对象的状态,(IsDirty)显然是对象的内部状态,而不是外部订户。如果属性被更改,那么如果(this.isInitialized){IsDirty=true;}否则不执行任何操作。但是如何确定这一点呢?如果EF正在进行加载,并且没有按照我问题中的第3个代码部分为DAL中的每个fetch和fill方法添加代码,则初始化。在这个阶段,它看起来像是一种扩展方法sort@rism我不明白为什么这个对象需要知道它是否“脏”,因为它不应该对它做任何事情,其他需要知道的东西都会订阅(假设它是实心的)。您可以订阅
ObjectContext
ObjectMaterialized
事件,将对象标记为已加载-请参阅我的更新。适配器。我使用的是DbContext,它继承自对象,没有此类事件。tyvm。
ObjectContext_OnObjectMaterialized(object sender, ObjectMaterializedEventArgs e).