EF 4.1,继承和共享主键关联=>指定表达式的ResultType不兼容

Fra*_*ans 5 entity-framework ef-code-first entity-framework-4.1

摘要

我有三个班:

  • Account
  • SpecialAccount(继承自Account)
  • Profile(0..1关系SpecialAccount)

换句话说,a SpecialAccount可以有0或1 Profiles.一个Profile必须有SpecialAccount.

在EF中,这只能设置为共享主键关系.

当查询profile和询问来自SpecialAccount(例如,"查找配置文件在哪里profile.SpecialAccount.Name == "blah")的东西时,我收到此错误:

{"指定表达式的ResultType与所需类型不兼容.
表达式ResultType为'Transient.reference [EFInheritanceTest.Account]',但
所需类型为'Transient.reference [EFInheritanceTest.SpecialAccount]'.
\r \nParameter名称:参数1 "}

细节

此代码说明了问题:

namespace EFInheritanceTest
{
  class Program
  {
      static void Main(string[] args)
      {
         using (var context = new MyContext())
         {
            var t = context.Profiles.Where(p => p.SpecialAccount.Name == "Fred");
            Console.WriteLine(t.Count());

            Console.ReadKey();
         }
      }
  }

  public class MyContext : DbContext
  {
     public DbSet<Account> Accounts { get; set; }
     public DbSet<SpecialAccount> SpecialAccounts { get; set; }
     public DbSet<Profile> Profiles { get; set; }

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
         base.OnModelCreating(modelBuilder);

         modelBuilder.Entity<SpecialAccount>().HasOptional(a => a.Profile);
         modelBuilder.Entity<Profile>().HasRequired(p => p.SpecialAccount);
     }
  }

 public class Account
 {
     public int ID { get; set; }
     public string Name { get; set; }
 }

 public class SpecialAccount : Account
 {
      public virtual Profile Profile { get; set; }
 }

 public class Profile
 {
     public int ID { get; set; }
     public string Summary { get; set; }
     public virtual SpecialAccount SpecialAccount { get; set; }
 }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止的调查

基本上,罪魁祸首似乎是共享的主键关联; 当Profile寻找它时SpecialAccount,它取而代之的是父Account对象.

我能看到的唯一解决方案是改变它;

public class SpecialAccount : Account
{
    public virtual ICollection<Profile> Profiles { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并在代码中维护规则而不是使用数据库.但它只是丑陋.

我在Connect上发现了这个相关问题这个错误 - 但是已经标记为已解决!

我怀疑这是EF4.1中的一个错误,但如果有人知道更好或者解决它,那么我会非常感谢任何见解.

Sla*_*uma 4

作为一种似乎无需更改模型定义即可工作的解决方法,您可以使用联接:

var t = from p in context.Profiles
        join s in context.SpecialAccounts
          on p.ID equals s.ID
        where s.Name == "Fred"
        select p;
var count = t.Count();
Run Code Online (Sandbox Code Playgroud)

或者使用扩展方法:

var t = context.Profiles
               .Join(context.SpecialAccounts,
                     p => p.ID,
                     s => s.ID,
                     (p, s) => new { s, p })
               .Where(r => r.s.Name == "Fred");
var count = t.Count();
Run Code Online (Sandbox Code Playgroud)

这不是很好,但您的原始查询不起作用的事实对我来说确实像是一个错误。(我已经使用 EF 4.1 进行了测试)