如何在EF 4中动态自定义POCO代理? [英] How can I dynamically customize a POCO proxy in EF 4?

查看:158
本文介绍了如何在EF 4中动态自定义POCO代理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想动态地自定义一些POCO类,使自己的虚拟成员能够编译LINQ to Entities查询。我知道 ObjectMaterialized 事件,但发生在类实例化之后。我想要能够自己创建代理,覆盖我想要的虚拟成员,然后传递给EF,这是可能的吗?



想象下面的POCO类:

  public class Consumer {
/ *这是在EF * / $ b $中具有关联的虚拟财产b public virtual ICollection< Message>消息{get;组; }

/ *这是我想优化的业务逻辑。 * /
public virtual Message GetMyLatestMessage()
{
return Messages.Where(m => m.Writer!= null&& m.Writer.ID == ID& & m.Type ==Message)
.OrderByDescending(m => m.Date)
.Take(1)
.FirstOrDefault();
}
}

当我对EF 4使用这个代码时,表达式 GetMyLatestMessage()成为一个SQL查询,但是我想预先编译这些表达式,因为它们中的一些变得很慢,每次解析都很慢。

解决方案

EF不提供拦截或替换为POCO生成的动态代理。此外,您显示的内容无法优化,因为它是Linq-to-Objects。 EF始终将所有消息加载到内存中,第一次执行它。这就是导航属性和延迟加载的工作原理,也可能是您的性能问题的原因。



如果要优化,请排除您的 GetMyLatestMessage 消费者分开课程并使用:

  public Message GetLatestMessage(int consumerId)
{
return context.Messages.Where(m => m.Consumer.Id == consumerId&&
m.Writer!= null&&b $ b m.Writer.ID == ID&&
m.Type ==Message)
.OrderByDescending(m => m.Date)
.Take(1)
.FirstOrDefault();

}


I would like to dynamically customize some POCO classes overriding myself the virtual members to be able to compile LINQ to Entities queries. I know about the ObjectMaterialized event but that happens after the class instantiation. I would like to be able to create the proxy myself, override the virtual members I want and then pass along to the EF, is that possible?

Imagine the following POCO class:

public class Consumer {
    /* That´s a virtual property with an association in EF */
    public virtual ICollection <Message> Messages { get; set; }

    /* That´s the business logic I would like to optimize. */
    public virtual Message GetMyLatestMessage()
    {
        return Messages.Where(m => m.Writer != null && m.Writer.ID == ID && m.Type == "Message")
                       .OrderByDescending(m => m.Date)
                       .Take(1)
                       .FirstOrDefault();
    }
 }

When I use this code against EF 4 the expression inside GetMyLatestMessage() becomes a SQL query, but I would like to pre-compile these expressions because some of them gets pretty slow to parse everytime.

解决方案

EF doesn't offer intercepting or replacing dynamic proxy generated for POCOs. Moreover what you show cannot be optimized because it is Linq-to-Objects. EF always loads all messages to memory first time you execute it. That is how navigation properties and lazy loading works and it is also probably reason for your performance problems.

If you want to make optimization exclude your GetMyLatestMessage from Consumer to separate class and use:

public Message GetLatestMessage(int consumerId)
{
    return context.Messages.Where(m => m.Consumer.Id == consumerId &&
                                       m.Writer != null && 
                                       m.Writer.ID == ID && 
                                       m.Type == "Message")
                  .OrderByDescending(m => m.Date)
                  .Take(1)
                  .FirstOrDefault();

}

这篇关于如何在EF 4中动态自定义POCO代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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