SQL图层:
我有一张桌子
实体框架层:
我有以下规则:所有优惠,其中State为null,是优惠优惠,State是真实的是Accepted offer,State is false是Declined offers。此外,部分字段仅用于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();
如果我尝试选择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;
关于建筑的补充说明:
我有3种类型的Offer实体。有:AcceptOffer,DeclineOffer和OutstandingOffer。
AcceptOffer:
- 用户ID
- 的ContactID
- 注释
- FirstContactDate
- LastContactDate
- [...和5-10个独特的字段......]
DeclineOffer:
- 用户ID
- 的ContactID
- 备注
- [...和5-10个独特的字段......]
OutstandingOffer:
- 用户ID
- 的ContactID
- FirstContactDate
- LastContactDate
- [...和5-10个独特的字段......]
如何正确完成?当然,我可以选择一条记录,从DB中删除并添加具有适当状态值的新记录,但是如何正常执行呢?
答案 0 :(得分:6)
创建对象后,无法更改对象的类型。你的对象模型似乎错了。 您要么删除未完成的要约并从中创建已接受的要约(看起来就像您当前正在做的那样),但在创建具有新标识的新对象时可能会丢失关系(您也可以在删除旧对象之前复制它们)。或者您希望保留相同的对象并更改其状态。
如果您想保持相同的身份,请预先composition over inheritance。
您的代码可能如下所示:
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; }
}
如果您仍想更改对象的类型并保持其标识,则可以使用存储过程;正如Noam Ben-Ami所说(EF的PM所有者):Changing the type of an entity。
答案 1 :(得分:3)
不要试图将这些自定义类添加到您的实体框架模型中,只需将它们创建为普通的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 */};