我想动态定制一些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查询,但我想预先编译这些表达式,因为其中一些表达式在每次解析时都很慢。
答案 0 :(得分:2)
EF不提供拦截或替换为POCO生成的动态代理。此外,您展示的内容无法进行优化,因为它是Linq-to-Objects。 EF总是在您第一次执行时将所有消息加载到内存中。这就是导航属性和延迟加载的工作原理,也可能是导致性能问题的原因。
如果您要进行优化,请将GetMyLatestMessage
从Consumer
排除到单独的类并使用:
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();
}