使用EF继承覆盖基类时发生非null异常

时间:2016-04-28 05:09:28

标签: entity-framework

我正在使用TPT继承,我的实体的关系如下: DepartmentCatalog derived form base class catalog and contain another entity Department

我的建议是从Deparment获取DepartmentCatalog的名称而不是基类目录,名称应该是readonly。所以我覆盖了这样的名字:

using System;
using Rednoble.CMS.Domain.CatalogsEntity;
using Rednoble.CMS.Domain.ExpertsEntity;
using System.ComponentModel.DataAnnotations.Schema;
using Rednoble.CMS.Domain.DepartmentEntity;

namespace Rednoble.CMS.Domain.CatalogsEntity
{
    [Table("DepartmentCatalog")]
    public class DepartmentCatalog : Catalog
    {
        public DepartmentCatalog()
            : base()
        {
        }

        public Guid DepartmentId { get; set; }

        public Department Department { get; set; }

        public override string Name
        {
            get
            {
                return Department.Name;
            }
        }
    }
}

但是当我从上下文中获取deparmentcatalog时,我得到了一个非null异常,因为EF在设置复杂属性之前得到了DepartmentCatalog的名称 - “Department”。

我不确定这是非法设计还是非法使用TPT继承。如何让我的工作完成,任何人都可以帮助我吗?

BTW,我正在使用VS2012和EF 6.0。

**更新***

我已经尝试过几个小时的热切加载和显式加载:

https://msdn.microsoft.com/en-us/data/jj574232.aspx

    var deptCatas = Context.Set<DepartmentCatalog>().Include(dc => dc.Department).Where(predicate);
    deptCatas.Load();//throw not null exception 

    var departmentCatalogs = _departmentCatalogReposiory.FindBy(r => r.DepartmentId == id);
    departmentCatalogs.FirstOrDefault();//throw not null exception 

这是我的映射:

public class CategoryMapping : EntityTypeConfiguration<Catalog>
{
    public CategoryMapping()
    {
        Property(r => r.Name).IsRequired().HasMaxLength(150);
        Property(r => r.PageUrl).HasMaxLength(500);
        Property(r => r.EnglishName).HasMaxLength(100);
        Property(r => r.CoverPictrue).HasMaxLength(500);
        HasMany(r => r.Rala_Catalog_Articles).WithRequired(r => r.Catalog).HasForeignKey(r => r.CatalogId);
        HasOptional(c => c.ViewTemplate).WithMany().HasForeignKey(r=>r.TemplateId).WillCascadeOnDelete(false);
    } 
}


public class DepartmentCategoryMapping
{
    public DepartmentCategoryMapping()
    {
        HasRequired(dc => dc.Department).WithMany(d => d.DepartmentCatalogs).HasForeignKey(dc => dc.DepartmentId).WillCascadeOnDelete(true);
    } 
}

我找到了一种方法来解决这个问题,只需要在第一次调用“FirstOrDefault”或“Load”作为name属性时检查Department是否为null,如果Department为null,则返回基目录的名称。但我认为这还不够好。其中一个缺陷是当部门名称发生变化时,DepartmentCatalog可能会变旧。这是我的代码:

   [Table("DepartmentCatalog")]
    public class DepartmentCatalog : Catalog
    {
        public DepartmentCatalog()
            : base()
        {
        }

        public Guid DepartmentId { get; set; }

        public Department Department { get; set; }

        public override string Name
        {
            get
            {
                if (Department == null)
                {
                    return base.Name;
                }
                else
                {
                    return Department.Name;
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

因为你没有加载部门。 您应该在查询中包含部门或使用延迟加载。

**更新***

对于渴望Loaing,您可以使用相同的代码:

MyContext.DepartmentCatalogs.Include(x=> x.Department).ToList()

对于延迟加载,您必须对Department属性使用virtual关键字。 顺便说一句,对于延迟加载,延迟加载和代理必须在您的配置中为真。

****编辑****

[ForeignKey("DepartmentId")]
public Department Department {get;set}

****更新****

context.DepartmentCatalogs.AsNoTracking().Include(x=>x.Department).FirstOrDefault();

解决这个问题的关键是AsNoTracking。