实体框架5-从数据库加载实体后寻找执行自定义代码的中心点 [英] Entity Framework 5 - Looking for Central Point to Execute Custom Code after Entity is Loaded from Database

查看:59
本文介绍了实体框架5-从数据库加载实体后寻找执行自定义代码的中心点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有Code First方法的Entity Framework 5,并使用Fluent API进行实体配置。我的项目有一个特定的产品实体,该实体从数据库中获取一半的数据,而另一半则从通过WCF客户端(用于管理产品清单的第三方系统)检索的数据合同中获取。数据合同是产品实体类的成员(我尚未决定的属性或方法)。

I am using Entity Framework 5 with Code First approach and using Fluent API for Entity configuration. My project has one particular Product Entity which gets half of its data from the database and the other half from a Data Contract retrieved via a WCF Client (its a 3rd party system used to manage product inventory). The Data Contract is a member of the Product Entity class (property or method I haven't decided yet).

我不希望WCF客户端逻辑中包含实体。我宁愿将此逻辑保留在存储库代码(DbContext,DbSet等)中。

I prefer not to have any WCF Client logic contain within the Entities. I'd prefer to keep this logic in Repository code (DbContext, DbSet, etc.).

那么有没有一种技术可以挂接到Entity Framework(或拦截)中从数据库检索产品实体后?我应该注意,产品实体在其他实体上显示为导航属性。如果可能发生钩子或拦截,那意味着在EF从数据库加载产品实体后,我可以立即从SOAP服务中检索数据协定。我的项目的好处是WCF客户端检索代码不需要在整个应用程序中重复进行。

So is there a technique to hook into Entity Framework (or intercept) just after a Product Entity is retrieved from the database? I should note the Product Entity appears as a navigation property on other Entities. If a hook or intercept is possible then what that means is I can retrieve the Data Contract from the SOAP service immediately after EF loaded the Product Entity from the database. The benefit for my project is the WCF Client retrieval code does not need to be repeated throughout the application.

我曾经想到的一个想法是为数据合同实现IDbSet, IDbSet将负责检索它。然后以某种方式诱使EF考虑其在产品实体上的导航属性。但是我不确定是否可以在同一DbContext中将数据库DbSet与非数据库IDbSet混合使用。还有另一个问题-EF如何知道如何从IDbSet植入中检索导航属性?我希望在投入时间之前先知道这个想法是否可行。我还希望知道从哪里开始寻找。

One idea I had was to implement IDbSet for the Data Contract and the IDbSet would be responsible for retrieving it. And then somehow trick EF into thinking its a navigation property on the Product Entity. But I wasn't sure if a database DbSet can be mixed with a non-database IDbSet all within the same DbContext. And also the other question - how would EF know to retrieve a navigation property from the IDbSet implantation? I'd prefer to know if this idea is possible before investing time into it. I'd also prefer to know where to start looking.

请注意,我已经使用.NET已有10多年了,但是对于EF5来说,它仍然相对较新我。

Please note I've been working with .NET for over 10 years but this EF5 stuff is still relatively new to me.

谢谢。

-Sam

推荐答案

今天,我在Entity Framework中发现了一个似乎正在寻找的事件。 ObjectContext.ObjectMaterialized事件。显然,DbContext实现了IObjectContextAdapter,该对象又公开了ObjectContext。从那里我可以订阅ObjectMaterialized事件。

Today I found an event in the Entity Framework that seems to be what I am looking for. ObjectContext.ObjectMaterialized Event. Apparently, DbContext implements IObjectContextAdapter which in-turn exposes the ObjectContext. From there I can subscribe to the ObjectMaterialized event.


MSDN读取
实体对象是从数据
源中的数据创建的,作为查询或装入操作的一部分。

MSDN Reads: Occurs when a new entity object is created from data in the data source as part of a query or load operation.

以下代码演示我如何使用ObjectMaterialized事件解决我的偏好之一,即我有一个中心点来放置WCF客户端访问逻辑。

The following code demonstrates how I used the ObjectMaterialized event to solve my problem in which one of my preferences was to have a central point to place the WCF client access logic.

// seperate assembly - does not use Domain.Repositories assembly
namespace Domain.Models
{
    // the data contract
    [DataContract]
    public class ProductInventoryState
    {
        [DataMember]
        public int StockStatus { get; set; }

        [DataMember]
        public IEnumerable<String> SerialNumbers { get; set; }

        // etc....
    }

    // the entity
    public class Product
    {
        public Guid Key { get; set; }
        public string ProductCode { get; set; }
        public ProductInventoryState InventoryState { get; set; }
        // etc....
    }
}

// seperate assembly - uses Domain.Models assembly
namespace Domain.Repositories
{
    public class MainRepository : DbContext
    {
        public MainRepository()
        {
            ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += ObjectContext_ObjectMaterialized;
        }

        protected void ObjectContext_ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
        {
            if (e.Entity == null)
                return;

            if (e.Entity is Product)
            {
                Product product = (Product)e.Entity;

                // retrieve ProductInventoryState from 3rd party SOAP API
                using (ThirdPartyInventorySystemClient client = new ThirdPartyInventorySystemClient())
                {
                    // use ProductCode to retrieve the data contract
                    product.InventoryState = client.GetInventoryState(product.ProductCode);
                }
            }
        }    
    }
}

这篇关于实体框架5-从数据库加载实体后寻找执行自定义代码的中心点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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