【问题标题】:Entity Framework base property mapping实体框架基础属性映射
【发布时间】:2018-10-26 14:07:51
【问题描述】:

您好,我的映射有问题。

我有层次结构的类:

  1. 纳税年度
  2. 所有者
  3. 经济单位
  4. 报告
  5. 报告项
  6. 发票

所有这些类都有一个基类“BaseEntity”和一个 parent 属性和 parent_id 属性。

发票父属性不是来自“ReportItem”类型,因为“Onwer”有一个单独的发票列表,所以类型是“BaseEntity”。

这很好用,我可以将其用作父级“ReportItem”和“Owner”。

但现在我想在父母之间“移动”发票。此时仅从“ReportItem”到“ReportItem”。

设置新的父节点:

foreach (var invoice in oldReportItem.Invoices)
{
    invoice.Parent = newReportItem;
}
ctx.SaveChanges();

这可以正常工作,但不正确。 EF 为我的父属性创建了三列。

  • Owner_Id
  • ReportItem_Id
  • Parent_Id

如果您插入发票,那么两列将获得相同的 ID。可以正常工作,但如果您设置了新的父级,则“Onwer_Id”或 ReportItem_Id 将设置为 null,并且 Parent_Id 只会被更新。

这是我的问题。我认为我的映射是错误的。谁能帮帮我?

Fluent-Api

modelBuilder.Entity<ReportItem>()
    .HasOptional(p => p.Parent)
    .WithMany(p => p.Items)
    .HasForeignKey(k => k.ParentId)
    .WillCascadeOnDelete(false);

基础实体:

public abstract class BaseEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public abstract String GetName();

    public DateTime? CreateDate { get; set; }
    public DateTime? LastEditDate { get; set; }

    public BaseEntity DeepCopy()
    {
        return (BaseEntity)MemberwiseClone();
    }
}

所有者:

public class Owner : BaseEntity
{
    public Owner()
    {
        Items = new ObservableCollection<EconomyUnit>();
        PrivateInvoices = new ObservableCollection<Invoice>();
    }

    [Required]
    public String Name { get; set; }

    [Required]
    public TaxYear Year { get; set; }
    public Guid? YearId { get; set; }

    public ICollection<EconomyUnit> Items { get; private set; }
    public ICollection<Invoice> PrivateInvoices { get; private set; }

    public override string GetName()
    {
        return Name;
    }
}

报告项目:

public class ReportItem : BaseEntity
{
    public ReportItem()
    {
        Items = new ObservableCollection<Invoice>();
    }

    [Required]
    public String Name { get; set; }

    public ICollection<Invoice> Items { get; private set; }

    public Guid? ParentId { get; set; }
    public Report Parent { get; set; }
}

发票:

public class Invoice: BaseEntity
{
    public String Name { get; set; }

    public Guid? ParentId { get; set; }

    public BaseEntity Parent { get; set; }

}

谢谢 歌词

【问题讨论】:

  • 我认为 EF 要正确加载它,它需要知道 Owners 和 ReportItems 之间的区别,因为它们没有存储在同一个表中。也许发票对象需要有一个 ReportItem 可选的 Parent 和一个可选的所有者,一个总是 null

标签: c# entity-framework entity-framework-6 ef-fluent-api


【解决方案1】:

好的,让我们从 OP 开始。

我有层次结构的类:

TaxYear Owner EconomyUnit 报告 ReportItem 发票

您的类结构表明 TaxYear 是可选的,因此它不能是父级(根据定义)。您的某些课程丢失了,因此我无法确定是否有任何其他关系存在缺陷。从表面上看你的陈述,你的类会更像这样(为了清楚起见,删除了无关的字段)

public abstract class BaseEntity - Unchanged

public class Owner : BaseEntity
{
    // Parent navigation    
    public Guid YearId { get; set; }
    public virtual TaxYear Year { get; set; }

    // Child navigation
    public virtual ICollection<EconomyUnit> Units { get; private set; }
}

public class EconomicUnit : BaseEntity
{
    // Parent navigation    
    public Guid OwnerId { get; set; }
    public virtual Owner Owner { get; set; }

    // Child navigation
    public virtual ICollection<Report> Reports { get; private set; }
}

public class Report : BaseEntity
{
    // Parent navigation    
    public Guid UnitId { get; set; }
    public virtual EconomicUnit Unit { get; set; }

    // Child navigation    
    public virtual ICollection<ReportItem> Items { get; private set; }
}

public class ReportItem : BaseEntity
{
    // Parent navigation    
    public Guid ReportId { get; set; }
    public virtual Report Report { get; set; }

    // Child navigation    
    public virtual ICollection<Invoice> Invoices { get; private set; }
}

public class Invoice : BaseEntity
{
    // Parent navigation    
    public Guid ReportItemId { get; set; }
    public virtual ReportItem ReportItem { get; set; }
}

如果您想查看所有者的发票列表,请尝试以下操作:

dbContext.Invoices.Where(a => a.ReportItem.Report.EconomicUnit.Owner.Id == <parameter>).Include(b => b.ReportItem.Report.EconomicUnit.Owner.TaxYear).ToList();

当然,您可以选择一个新的 DTO 对象来反转关系 Owner ==> Invoices。

【讨论】:

    猜你喜欢
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多