【问题标题】:How can I dynamically customize a POCO proxy in EF 4?如何在 EF 4 中动态自定义 POCO 代理?
【发布时间】:2011-03-28 20:24:06
【问题描述】:

我想动态自定义一些 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 查询,但我想预编译这些表达式,因为其中一些表达式每次解析都很慢。

【问题讨论】:

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


    【解决方案1】:

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

    如果你想优化从Consumer 中排除你的GetMyLatestMessage 以分离类并使用:

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

    【讨论】:

    • 感谢有关导航属性的提示,但我有其他直接关于我想预编译的 ObjectSet 的查询。似乎我的类层次结构使查询的编译过程非常缓慢。
    • 您可以在别处定义已编译的查询。编译后的查询应该在实体之间共享,因为编译过程很昂贵。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多