实体框架 – 实体框架5 – 在实体从数据库加载之后,寻找中心点执行自定义代码

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

我更希望在实体中不包含任何WCF客户端逻辑.我更喜欢将这个逻辑保留在Repository代码(DbContext,DbSet等)中.

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

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

请注意,我一直在使用.NET十多年,但这个EF5的东西对我来说还是比较新的.

提前致谢.

萨姆

解决方法

今天我在实体框架中发现了一个似乎正在寻找的事件. ObjectContext.ObjectMaterialized Event.显然,DbContext实现了IObjectContextAdapter,这反过来暴露了ObjectContext.从那里我可以订阅ObjectMaterialized事件.

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客户端访问逻辑的问题.

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

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 &#39;EastRiver&#39; 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...