POCO类定义如下:
public partial class Quoter
    {
        
    
        public int ID { get; set; }
        public string Account { get; set; }
        public string Password { get; set; }
        public string Contactor { get; set; }
        public System.DateTime RegisterDt { get; set; }
        public int Status { get; set; }
        public bool Active { get; set; }
    
        
    }
public partial class Recycler : Quoter
    {
        public Recycler()
        {
            this.ContactInfo = new RecylerContactInfo();
            this.CertificatedInfo = new RecylerCertificatedInfo();
            this.ShopInfo = new RecylerShopInfo();
            this.ClientAppStat = new RecylerClientAppStat();
        }
    
        public string Description { get; set; }
        public int Region { get; set; }
        public bool IsReal { get; set; }
        public int Group { get; set; }
        public string Re { get; set; }
        public Nullable<int> Order { get; set; }
    
        public RecylerContactInfo ContactInfo { get; set; }
        public RecylerCertificatedInfo CertificatedInfo { get; set; }
        public RecylerShopInfo ShopInfo { get; set; }
        public RecylerClientAppStat ClientAppStat { get; set; }
    
        public virtual Region RegionInfo { get; set; }
        public virtual RecylerGroup RecylerGroup { get; set; }
        public virtual RecylerStat RecylerStat { get; set; }
        public virtual RecyclerAccount RecyclerAccount { get; set; }
    }public partial class RecyclerAccount
    {
        public int Recycler { get; set; }
        public int Credit { get; set; }
        public int Sum { get; set; }
        public int Available { get; set; }
        public string Guarantee { get; set; }
    
        public virtual Recycler RecyclerInfo { get; set; }
    }现在我要查找recycler并且预加载它的导航属性RecyclerAccount,我用下面两只方式尝试均不成功
dbContext.set<Recycler>().include(r=>r.RecyclerAccount).where(r.ID == 1).ToList();
这里抛出的异常信息是:{"指定表达式的 ResultType 与要求的类型不兼容。表达式 ResultType 为“Transient.reference[HuiShou.Quoter]”,但要求的类型为“Transient.reference[HuiShou.Recycler]”。\r\n参数名: arguments[0]"}
我又换成下面的方式查找
dbContext.set<Quoter>().oftype<Recycler>().include(r=>r.RecyclerAccount).where(r=>r.ID == 1).ToList();
这次代码可以顺利执行,但是执行结果发现recycler的导航属性RecyclerAccount没有预加载进来还是为null,看了entityframework生成的sql代码确实没有关联recycleraccount表,只关联了quoter和recycler表这是怎么回事,正确的处理方法是怎么样的啊

解决方案 »

  1.   

    从Recycler与RecyclerAcount的最后两行代码看,你准备建立1:1的关系,这需要用Annotion或者Fluent API指定依赖方向
      

  2.   


    能详细一点吗,我被这个问题困恼了很久,而且我发现我用dbContext.set<Quoter>.where(q=>q.ID ==1).ToList();返回的结果是ienumable<Recycler>类型的,我现在对entityframework的继承已经觉得是不是有设计上的Bug
      

  3.   

    因为recycleraccount的关联是这样的recycleraccount的recycler字段即是recycleraccount的主键,同时是recycler表的外键,本来应该是1:M的关系,但因为recycler字段是recycleraccount的主键所以变成了1:1的关系
      

  4.   

    我将就我的练习,模拟了你的要求。象下面这样的建模,可以实现Recycler从Quoter派生,并与Account实现1:1的对应关系。
    partial class BreakAwayContext
    {
    public DbSet<Quoter> Quoters { get; set; }
    public DbSet<Account> Accounts { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    modelBuilder.Entity<Account>().HasRequired(a => a.RecyclerRef).WithRequiredDependent(r => r.AccountRef);
    }
    }public abstract class Quoter
    {
    public int QuoterId { get; set; }
    public string Text { get; set; }
    }public class Recycler : Quoter
    {
    public string Description { get; set; }
    public Account AccountRef { get; set; }
    }public class Account
    {
    public int AccountId { get; set; }
    public Recycler RecyclerRef { get; set; }
    }
      

  5.   


    能简单说一下你业务建模里这3个对象之间的关系吗?不用说明谁是PK/FK,只说明三个对象间的关系即可。我越看越不明白你的需求了。
      

  6.   


    好的,
    Quoter是一个基类,它现在地下有一个派生类交Recycler,这两个类都有对应的数据表,通过TPT方式实现继承,
    每个Recycler都一个唯一的RecyclerAccount
      

  7.   

    没有数据吧?没有就重建吧。有的话,就要想点办法了。那天你发的帖子,我也能建立B从A派生,B与C形成1:M的关系的模型。Relationship是EF里的难点了,给你推荐一个人的blog吧。这是该系列的第一篇:
    http://weblogs.asp.net/manavi/archive/2011/03/27/associations-in-ef-4-1-code-first-part-1-introduction-and-basic-concepts.aspx
      

  8.   

    Quoter与Recycler如何实现表的存储,无关紧要。关键是要建立Recycler与Account之间的1:1关系。这个可以通过象我上面那样的Fluent API实现,或者使用Data Annotation。我之前的代码已经可以实现你的要求。
      

  9.   

    刚才贴的已经就是全部代码了啊。
    public class BreakAwayContext : DbContext
    {
    public DbSet<Quoter> Quoters { get; set; }
    public DbSet<Account> Accounts { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    modelBuilder.Entity<Account>()
    .HasRequired(a => a.RecyclerRef)
    .WithRequiredDependent(r => r.AccountRef);
    }
    }public abstract class Quoter
    {
    public int QuoterId { get; set; }
    public string Text { get; set; }
    }public class Recycler : Quoter
    {
    public string Description { get; set; }
    public Account AccountRef { get; set; }
    }public class Account
    {
    public int AccountId { get; set; }
    public Recycler RecyclerRef { get; set; }
    }public class PocoExercise
    {
            static void Main(string[] args)
            {
                    // 这里自己添加一点CUD代码试一下        }
    }
      

  10.   

    新建一个控制台应用,把上面的代码贴进去。如果你用的SQL Server Express,那么EF会自动建立数据库连接并生成对应的表。如果不是Express,需要你自己配置数据库连接串,比如在app.config里,或者传送给DbContext的构造子。
      

  11.   

    Sorry,刚才只留意你要建立Recycle与Account之间1:1的关系去了。触发异常,是因为Include<T,  TProperty>()这里的问题。由于Quoter是抽象类,且Recycler是用的Quoter的PK与Account建立的关系,因此我暂时想到的办法,是换作如下的思路。即适当修改一下Fluent,建立Quoter与Account之间1:1的关系。
    modelBuilder.Entity<Account>()
    .HasRequired(a => a.QuoterRef)
    .WithRequiredDependent(r => r.AccountRef);然后用类似下面这样的查询:
    var query = context.Quoters
    .Include(q => q.AccountRef)
    .OfType<Recycler>()
    .Where(r=>r.QuoterId == 1)
    .ToList();
      

  12.   

    对的,这样处理是可以的,但这样做account就变成了quoter的导航属性了,我其实是想让account成为recycler的导航属性,这样从面向domain上来讲更有意义,因为这个account是为recycler建立的,并不是所有的quoter都有account
      

  13.   

    找到问题了,不在Include<T, TProperty>(),而在你最后的ToList()。你把ToList()去除,这个查询就能正常执行了,不过我还没Seed数据进去,不知道这个查询是否能返回我们需要的结果。先睡觉了,明天我再看看。
      

  14.   


    ToList去掉了,数据怎么出来? 辛苦你了老兄
      

  15.   

    想了一中午,也没找到合适的办法解决这个问题。昨晚睡觉前,我把你的问题提交到StackOverflow了,有空就去看看人家的回复吧。Why can't I do ToList()?