在CTP4代码中首先使用CreateSourceQuery [英] Using CreateSourceQuery in CTP4 Code First

查看:104
本文介绍了在CTP4代码中首先使用CreateSourceQuery的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我猜这是不可能的,但我会把它丢在那里。在使用CTP4中的EF4 CodeFirst API进行编程时,是否可以使用CreateSourceQuery?我想热切地加载附加到属性集合的属性,如下所示:

  var sourceQuery = this.CurrentInvoice.PropertyInvoices .CreateSourceQuery(); 
sourceQuery.Include(Property)。ToList();

但是当然CreateSourceQuery在 EntityCollection< T> ,而CodeFirst使用纯旧的 ICollection (显然)。有没有办法转换?



我已经下面的工作,但这不是我正在寻找的。任何人都知道如何从下面的内容到上面的代码(下面的代码来自继承DbContext的类)?

  ObjectSet& ; OSPeople = base.ObjectContext.CreateObjectSet< Person>(); 
OSPeople.Include(Pinner => Pinner.Books).ToList();

谢谢!



编辑:这是我的版本的zeeshanhirani发布的解决方案 - 谁的书顺便说一句!

 动态结果; 

if(invoice.PropertyInvoices是EntityCollection< PropertyInvoice>)
result =(invoices.PropertyInvoices as EntityCollection< PropertyInvoice>)。CreateSourceQuery()。Yadda.Yadda.Yadda
else
//必须是单元测试!
result = invoices.PropertyInvoices;

return result.ToList();

EDIT2:



意识到您在使用动态时不能调度扩展方法。所以我想我们并不像Ruby那样动态,但是上面的例子很容易被修改为与这个限制相匹配。



EDIT3:



如zeeshanhirani的博客文章中所述,只有(并且只有)你有启用代码的代理才会有效,如果全部的属性被声明为虚拟的。这是另一个版本的方法可能会使用CreateSourceQuery与POCO

  public class Person {
public virtual int ID {get;组; }
public virtual string FName {get;组; }
public virtual string LName {get;组; }
public virtual double Weight {get;组; }
public virtual ICollection< Book>书籍{get;组; }
}

public class Book {
public virtual int ID {get;组; }
public virtual string标题{get;组; }
public virtual int Pages {get;组; }
public virtual int UserID {get;组; }
public virtual ICollection<类型>流派{get;组; }
public virtual Person Owner {get;组; }
}

public class类型{
public virtual int ID {get;组; }
public virtual string Name {get;组; }
public virtual类型ParentGenre {get;组; }
public virtual ICollection< Book>书籍{get;组;
}

public class BookContext:DbContext {
public void PrimeBooksCollectionToIncludeGenres(Person P){
if(P.Books is EntityCollection< Book>)
(P.Books as EntityCollection< Book>)。CreateSourceQuery()。Include(b => b.Genres).ToList();
}


解决方案

绝对有可能做所以。如果您使用 virtual 关键字标记了集合属性,那么在运行时,实际的具体类型为 ICollection 将为 EntityCollection 支持 CreateSourceQuery 以及默认代码生成器附带的所有好处。以下是我将如何做。

  public class发票
{
public virtual ICollection PropertyInvoices {get; set}
}

动态发票= this.Invoice;
动态发票= invoice.PropertyInvoices.CreateSourceQuery()。Include(Property);

我写了一篇类似的博客文章。请注意,依靠 ICollection 内部实现转换为 EntityCollection 不是一个好习惯。
以下是您可能会发现有用的博客文章



http://weblogs.asp.net/zeeshanhirani/archive/2010/03/ 24 / registration-with-associationchanged-event-on-poco-with-change-tracking-proxy.aspx


I'm guessing this is impossible, but I'll throw it out there anyway. Is it possible to use CreateSourceQuery when programming with the EF4 CodeFirst API, in CTP4? I'd like to eagerly load properties attached to a collection of properties, like this:

var sourceQuery = this.CurrentInvoice.PropertyInvoices.CreateSourceQuery();
sourceQuery.Include("Property").ToList();

But of course CreateSourceQuery is defined on EntityCollection<T>, whereas CodeFirst uses plain old ICollection (obviously). Is there some way to convert?

I've gotten the below to work, but it's not quite what I'm looking for. Anyone know how to go from what's below to what's above (code below is from a class that inherits DbContext)?

ObjectSet<Person> OSPeople = base.ObjectContext.CreateObjectSet<Person>();
OSPeople.Include(Pinner => Pinner.Books).ToList();

Thanks!

EDIT: here's my version of the solution posted by zeeshanhirani - who's book by the way is amazing!

dynamic result;

if (invoice.PropertyInvoices is EntityCollection<PropertyInvoice>) 
   result = (invoices.PropertyInvoices as EntityCollection<PropertyInvoice>).CreateSourceQuery().Yadda.Yadda.Yadda 
else 
   //must be a unit test! 
   result = invoices.PropertyInvoices; 

return result.ToList();

EDIT2:

Ok, I just realized that you can't dispatch extension methods whilst using dynamic. So I guess we're not quite as dynamic as Ruby, but the example above is easily modifiable to comport with this restriction

EDIT3:

As mentioned in zeeshanhirani's blog post, this only works if (and only if) you have change-enabled proxies, which will get created if all of your properties are declared virtual. Here's another version of what the method might look like to use CreateSourceQuery with POCOs

public class Person {
    public virtual int ID { get; set; }
    public virtual string FName { get; set; }
    public virtual string LName { get; set; }
    public virtual double Weight { get; set; }
    public virtual ICollection<Book> Books { get; set; }
}

public class Book {
    public virtual int ID { get; set; }
    public virtual string Title { get; set; }
    public virtual int Pages { get; set; }
    public virtual int OwnerID { get; set; }
    public virtual ICollection<Genre> Genres { get; set; }
    public virtual Person Owner { get; set; }
}

public class Genre {
    public virtual int ID { get; set; }
    public virtual string Name { get; set; }
    public virtual Genre ParentGenre { get; set; }
    public virtual ICollection<Book> Books { get; set; }
}

public class BookContext : DbContext {
    public void PrimeBooksCollectionToIncludeGenres(Person P) {
        if (P.Books is EntityCollection<Book>)
            (P.Books as EntityCollection<Book>).CreateSourceQuery().Include(b => b.Genres).ToList();
    }

解决方案

It is definately possible to do so. If you have marked you collection property with virtual keyword, then at runtime, you actual concrete type for ICollection would be EntityCollection which supports CreateSourceQuery and all the goodies that comes with the default code generator. Here is how i would do it.

public class Invoice
{
    public virtual ICollection PropertyInvoices{get;set}
}

dynamic invoice = this.Invoice;
dynamic invoice = invoice.PropertyInvoices.CreateSourceQuery().Include("Property");

I wrote a blog post on something similar. Just be aware that it is not a good practice to rely on the inner implementation of ICollection getting converted to EntityCollection. below is the blog post you might find useful

http://weblogs.asp.net/zeeshanhirani/archive/2010/03/24/registering-with-associationchanged-event-on-poco-with-change-tracking-proxy.aspx

这篇关于在CTP4代码中首先使用CreateSourceQuery的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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