简体   繁体   English

实体框架继承

[英]Entity Framework inheritance

SQL Layer: SQL层:

I have a table 我有一张桌子

在此输入图像描述

Entity Framwork Layer: 实体框架层:

I have the following rule: all Offers, which have State is null, are Outstanding offers, State is true are Accepted offers, State is false are Declined offers. 我有以下规则:所有要约,其中State为null,是优惠要约,State是真实的是已接受的要约,State is false是拒绝要约。 Also, part of fields used only for Outstanding, part - only for Accepted etc... I use Database first approach, so, I updated EF model from DB and renamed Offer entity to OfferBase and created 3 child classes: 此外,部分字段仅用于Outstanding,part - 仅用于Accepted等...我使用Database first方法,因此,我从DB更新EF模型并将Offer实体重命名为OfferBase并创建了3个子类:

在此输入图像描述

it works fine for add/select entities/records. 它适用于添加/选择实体/记录。 Right now I want to "move" offer from outstanding to accept offer, so, I need to set Status=true (from Status is null) for appropriate record. 现在我想要从优秀到接受报价“移动”报价,所以,我需要设置Status = true(从Status为null)以获得适当的记录。 But how to do it by Entity Framework? 但是如何通过实体框架来实现呢? If I try to select outstanding offer as Accept offer I get an null reference (and clearly why) 如果我尝试选择未完成的报价作为接受报价,我会得到一个空参考(显然为什么)

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

if I try to select as OfferBase entity I get the following error: 如果我尝试选择作为OfferBase实体,我会收到以下错误:

Unable to cast object of type 'System.Data.Entity.DynamicProxies.OfferOutstanding_9DD3E4A5D716F158C6875FA0EDF5D0E52150A406416D4D641148F9AFE2B5A16A' to type 'VTS.EFModels.OfferAccepted'. 无法将“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;

ADDED NOTES ABOUT ARCHITECTURE: 关于建筑的附加说明:

I have 3 types of Offer entity. 我有3种类型的Offer实体。 There are: AcceptOffer, DeclineOffer and OutstandingOffer. 有:AcceptOffer,DeclineOffer和OutstandingOffer。

AcceptOffer: AcceptOffer:

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

DeclineOffer: DeclineOffer:

  • UserID 用户身份
  • ContactID 使用ContactID
  • Notes 笔记
  • [... and 5-10 the unique fields...] [...和5-10个独特的领域......]

OutstandingOffer: OutstandingOffer:

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

How to do it correctly? 怎么做正确? Of course, I can select a record, remove from DB and add new with appropriate state value, but how to do it normally? 当然,我可以选择一条记录,从DB中删除并添加具有适当状态值的新记录,但如何正常执行呢?

You can't change the type of an object once it's created. 创建对象后,无法更改对象的类型。 Your object model seems wrong. 你的对象模型似乎错了。 Either you delete the outstanding offer and create an accepted offer from it (looks like what you are currently doing) but you may lose relations as you created a new object with a new identity (you can also copy them before removing the old object). 您要么删除未完成的要约并从中创建已接受的要约(看起来就像您当前正在做的那样),但在创建具有新标识的新对象时可能会丢失关系(您也可以在删除旧对象之前复制它们)。 Or you want to keep the same object and change its state. 或者您希望保留相同的对象并更改其状态。

If you want to keep the same identity then preffer composition over inheritance . 如果你想保持相同的身份,那么就要比继承更好。

Your code could look like this : 您的代码可能如下所示:

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; }
}

If you still want to change the type of the object and keep its identity then you may use stored procedures ; 如果您仍想更改对象的类型并保持其标识,则可以使用存储过程; as stated by Noam Ben-Ami (PM owner for EF) : Changing the type of an entity . 正如Noam Ben-Ami(EF的PM所有者)所述: 改变实体的类型

Rather than trying to add these custom classes to your entity framework model, just create them as normal c# classes and then use a projection to convert from the entity framework generated class to your own class eg 而不是尝试将这些自定义类添加到您的实体框架模型,只需将它们创建为普通的c#类,然后使用投影从实体框架生成的类转换为您自己的类,例如

var accepteOffers= from i in _db.Offers
                   where i.ID == 1 && i.Status == true
                   select new OfferAccepted { AcceptDate = i.AcceptDate, StartTime = i.StartTime /* map all releaveant fields here */};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM