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

标签 entity-framework entity-framework-4.1 ef-code-first

摘要

我有三个类(class):

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

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

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

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

    {"The ResultType of the specified expression is not compatible with the required type.
    The expression ResultType is 'Transient.reference[EFInheritanceTest.Account]' but
    the required type is 'Transient.reference[EFInheritanceTest.SpecialAccount]'.
    \r\nParameter name: arguments1"}



    详情

    这段代码说明了这个问题:
    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; }
     }
    }
    

    调查至今

    基本上,罪魁祸首似乎是共享主键关联;当Profile去寻找它的SpecialAccount ,而是获取父项 Account目的。

    我能看到的唯一解决方案是像这样改变它;
    public class SpecialAccount : Account
    {
        public virtual ICollection<Profile> Profiles { get; set; }
    }
    

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

    我发现这个相关 questionthis bug在连接上 - 但它已被标记为已解决!?

    我怀疑这是 EF4.1 中的一个错误,但如果有人知道更好的方法或解决方法,那么我将非常感谢您提供任何见解。

    最佳答案

    作为一种似乎在不更改模型定义的情况下工作的解决方法,您可以使用连接:

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

    或者使用扩展方法:
    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();
    

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

    关于entity-framework - EF 4.1, 继承与共享主键关联 => 指定表达式的 ResultType 不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6648895/

    相关文章:

    c# - 数据库迁移后更新 Entity Framework EDMX 模型

    c# - 如何优化读取访问?

    asp.net-mvc-3 - SQLite CreateDatabase 不支持错误

    .net - 如何使用 Entity Framework 4.1 Fluent API 映射枚举?

    data-annotations - 如何使用代码优先和数据注释在 Entity Framework 4.1 中创建一对多关系?

    asp.net-mvc-3 - EF 4.1-模型关系

    sql-server - 基于外键 EF 的主键

    c# - Entity Framework 4.3.1 到 6 EDMX (ObjectContext)

    c# - 加载大量要在 WrapPanel 中显示的图像

    c# - Entity Framework 代码优先 : map list of ids to entity using reference table