如何在EF 4中动态自定义POCO代理?

时间:2011-03-28 20:24:07

标签: entity-framework-4 linq-to-entities poco

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

想象一下以下的POCO课程:

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

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

1 个答案:

答案 0 :(得分:2)

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

如果您要进行优化,请将GetMyLatestMessageConsumer排除到单独的类并使用:

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

}