2

在 VS2012(.NET 4.5 和实体框架 5 )

暴露继承关系时,导致编译时错误:

您不能对类型“MrTree.SubSubClass”的属性“InnerString”使用 Ignore 方法,因为此类型继承自映射此属性的类型“MrTree.BaseClass”。要从模型中排除此属性,请对基本类型使用 NotMappedAttribute 或 Ignore 方法。

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyDbcontext db = new MyDbcontext();
            int i = db.SubSubClasses.Count();
        }
    }

    public class BaseClass
    {
        [NotMapped]
        public string InnerString { get; set; }
    }

    public class SubClass : BaseClass
    {
    }

    public class SubSubClass : SubClass
    {
    }

    public class MyDbcontext : DbContext
    {
        public DbSet<SubSubClass> SubSubClasses { get; set; }
        public DbSet<SubClass> SubClasses { get; set; }

    }
}

你能告诉我有什么问题吗?

4

3 回答 3

1

我找到了解决这个问题的方法,我自己也经历过。我确实发布了一些关于可能导致问题的补充信息,但它被一些自负的书呆子删除了,他们认为这不值得。所以这是我对这个问题的回答 - 可能不完全正确,但它对我有用,所以请不要删除这个书呆子先生,以防它帮助别人。

首先,此问题仅影响不直接使用 NotMapped 属性继承抽象类的类,而是根据原始声明从本身继承自基类的另一个类继承的类。

使用类似于以下类设置的内容对我有用:

基类:

public abstract class EntityBase
{
   public virtual int Id { get; set; } // this will be mapped
   public virtual int DoNotMap { get; set; } // this should be ignored   
}

一级继承

public class Contact : EntityBase
{
  public string Name { get; set; }
}

二级继承

public class Employee : Contact
{
  public DateTime StartDate { get; set; }
}

创建一个继承自 EntityTypeConfiguration 的通用配置类:

public class DataEntityBaseConfiguration<T> 
  : EntityTypeConfiguration<T> where T : EntityBase
{
  public DataEntityBaseConfiguration()
  {
    Ignore(x => x.DoNotMap);
  }
}

为直接从 EntityBase 类继承的所有第一级继承创建配置类,即:

public class ContactConfiguration : DataEntityBaseConfiguration<Contact>
{
   // place any further configuration rules in the constructor
}

解决方法:任何间接继承自 EntityBase的类,只需创建一个继承自 EntityTypeConfiguration 的 Configuration 类:

public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
  // place any further configuration rules in the constructor
}

在您的 DataContext 中,在 OnModelCreating 方法中,添加您的配置:

modelBuilder.Configurations.Add(new ContactConfiguration()); modelBuilder.Configurations.Add(new EmployeeConfiguration());

假设在这种情况下采用 TPT 方法,将专用版本 Employee 映射到其自己的表,并与 Contact 具有 FK 关系:

 modelBuilder.Entity<Contact>().Map<Employee>(m => m.ToTable("Employees"));

至少对我而言,这会创建一个没有“DoNotMap”属性的联系人表和一个没有“DoNotMap”表且与联系人有PK/FK 关系的员工表。即使我没有从 Employee Configuration 的 EntityBaseConfiguration 继承,它仍然以某种方式选择了 Ignore 并将其排除在外。我假设如果我们采用 TPH 方法,我们最终会得到一个单独的 Contact 表和 Discriminator 列。TPC 显然会重新创建 Employee 表中的所有 Contact 属性,但我不确定它是否还会创建 DoNotMap 属性 - 将在我有空时进行测试。

简而言之,回到最初的问题,我不确定为什么 NotMapped 属性和 Ignore 都会发生这种情况。当我的 EmployeeConfiguration 从 EntityBaseConfiguration 继承时出现错误。我不热衷于解决方法,因为它首先错误在其声明中是错误的,其次,即使解决方案现在非常简单,它也是一个很容易再次陷入的错误。

希望能帮助任何在这个继承问题上苦苦挣扎的人。

问候

于 2013-01-03T20:52:15.177 回答
1

主键必须包含在 POCO 类定义 A 中的事实已经意味着 A 不是 POCO 对象。您不能忽略 POCO 对象的属性

于 2013-08-19T21:45:49.490 回答
0

你有一个叫你的财产InnerStringSubSubClass?这就是错误的意思,尽管您的示例代码中没有列出它。

您上面的代码对我有用,但我必须添加一个 PK,这是整个控制台应用程序:

   public class BaseClass
   {
      public int Id { get; set; }
      [NotMapped]
      public string InnerString { get; set; }
   }

   public class SubClass : BaseClass
   {
   }

   public class SubSubClass : SubClass
   {
   }

   public class MyDbcontext : DbContext
   {
      public DbSet<SubSubClass> SubSubClasses { get; set; }
      public DbSet<SubClass> SubClasses { get; set; }
   }

   class Program
   {
      static void Main( string[] args )
      {
         var context = new MyDbcontext();

         context.SubSubClasses.Add(new SubSubClass());
         context.SaveChanges();
      }
   }

以及它创建的数据库:

在此处输入图像描述

于 2012-09-11T03:20:39.790 回答