实体框架继承

Ole*_* Sh 4 c# inheritance entity-framework

SQL层:

我有一张桌子

在此输入图像描述

实体框架层:

我有以下规则:所有要约,其中State为null,是优惠要约,State是真实的是已接受的要约,State is false是拒绝要约.此外,部分字段仅用于Outstanding,part - 仅用于Accepted等...我使用Database first方法,因此,我从DB更新EF模型并将Offer实体重命名为OfferBase并创建了3个子类:

在此输入图像描述

它适用于添加/选择实体/记录.现在我想要从优秀到接受报价"移动"报价,所以,我需要设置Status = true(从Status为null)以获得适当的记录.但是如何通过实体框架来实现呢?如果我尝试选择未完成的报价作为接受报价,我会得到一个空参考(显然为什么)

// record with ID=1 exists, but State is null, so, EF can not find this record and offer will be null after the following string
var offer = (from i in _db.OfferBases.OfType<EFModels.OfferAccepted>() where i.ID == 1 select i).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

如果我尝试选择作为OfferBase实体,我会收到以下错误:

无法将"System.Data.Entity.DynamicProxies.OfferOutstanding_9DD3E4A5D716F158C6875FA0EDF5D0E52150A406416D4D641148F9AFE2B5A16A"类型的对象转换为"VTS.EFModels.OfferAccepted"类型.

    var offerB = (from i in _db.OfferBases where i.ID == 1 select i).FirstOrDefault();
    var offer = (EFModels.OfferAccepted)offerB;
Run Code Online (Sandbox Code Playgroud)

关于建筑的附加说明:

我有3种类型的Offer实体.有:AcceptOffer,DeclineOffer和OutstandingOffer.

AcceptOffer:

  • 用户身份
  • 使用ContactID
  • 笔记
  • FirstContactDate
  • LastContactDate
  • [...和5-10个独特的领域......]

DeclineOffer:

  • 用户身份
  • 使用ContactID
  • 笔记
  • [...和5-10个独特的领域......]

OutstandingOffer:

  • 用户身份
  • 使用ContactID
  • FirstContactDate
  • LastContactDate
  • [...和5-10个独特的领域......]

怎么做正确?当然,我可以选择一条记录,从DB中删除并添加具有适当状态值的新记录,但如何正常执行呢?

Gui*_*ume 6

创建对象后,无法更改对象的类型.你的对象模型似乎错了.您要么删除未完成的要约并从中创建已接受的要约(看起来就像您当前正在做的那样),但在创建具有新标识的新对象时可能会丢失关系(您也可以在删除旧对象之前复制它们).或者您希望保留相同的对象并更改其状态.

如果你想保持相同的身份,那么就要比继承更好.

您的代码可能如下所示:

public class Offer
{
  public int Id { get; set; }
  public virtual OfferState State { get; set }
}

public class OfferState
{
  public int OfferId { get; set; }
  public string Notes { get; set; }
}

public class AcceptedOfferState : OfferState
{
  public DateTimeOffset AcceptDate { get; set; }
}

public class DeclinedOfferState : OfferState
{
  public DateTimeOffset DeclinedDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果您仍想更改对象的类型并保持其标识,则可以使用存储过程; 正如Noam Ben-Ami(EF的PM所有者)所述:改变实体的类型.