实体框架多态关联 [英] Entity Framework Polymorphic associations

查看:163
本文介绍了实体框架多态关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将很快使用实体框架进行预订系统(从零开始)。



我一直在做几个原型,试图找出什么我想在项目开始之前做(我还在和客户讨论需求等)。



考虑这种情况:



我有一个预订,预订可以有相关的资源,可以预订,但这些资源可以是不同的,并有不同的字段等。





I从来没有真正使用过EF,所以我不知道如何实现这种多态性,我在其他项目(我们一直在使用原始SQL)中使用。



C#模型将如下所示:

  public class Booking 
{
public int BookingID {get;组; }
public DateTime StartTime {get;组; }
public DateTime EndTime {get;组; }
public IRessource Ressources {get;组; }
...
}

public interface IRessource
{
public int RessourceTypeId {get;组; }
}

public class房间:IRessource
{
public int RoomID {get;组; }
public int RessourceTypeId {get;组;
...
}

public class Car:IRessource
{
public int CarID {get;组; }
public int RessourceTypeId {get;组; }
...
}

这是否可以实现,如果是,那么怎么样
查询甚至会看起来如何?

解决方案

是的,绝对是 >

听起来你真的想要一个 Table Per Type(TPT)关系。这表示标准的 is-a / has-a 外键关系。请注意,默认情况下,实体框架使用表层次结构(TPH)。



以下是一些链接:





我强烈建议您自行浏览这些链接,但要提取的要点是您使用某些东西如:

  modelBuilder.Entity& LT; IRessource>()ToTable( IRessources); 
modelBuilder.Entity< Room>()。ToTable(Rooms);
modelBuilder.Entity< Car>()。ToTable(Cars);

这两个都继承自你的 IRessource 演示代码如上。然后,您可以在这些单独的表和中央的 IRessource 表之间进行连接,以获取有关各个实体的所有信息。



如下所示: SELECT * FROM IRessource i JOIN Room r ON i.id == r.id p>

但是,如果您使用 Web API 控制器,您经常会发现,如果您只是拉整个房间 POCO,您将一次性获得所有房产,而无需加入!





根据我的经验,我也发现如果你不使用接口或抽象类,那么通常情况会更顺利,因为如果你这样做,你必须做数据传输对象(DTO)偶尔传输数据,因为您无法实例化这些类型的对象。事情可能会有点混乱 - 特别是如果你不确定你在做什么。为了帮助你理解,想想一个控制器,你想通过它来传递一个通用的 IRressource - 它会尝试将这些对象转换成一个可以不被实例化。坏消息!所以,简单的解决方案只是使基类和继承类的正常类。


I'm going to use Entity Framework soon for a Booking System ( made from scratch ).

I have been doing a few Prototypes, trying to figure out what I want to do before the project is started (I'm still discussing requirements etc. with the client).

Consider this case:

I have a Booking, and a booking can have associated Ressources, that can be booked, but these ressource can be different, and have different Fields etc.

I have never really used EF before, so I don't know how I can achieve this kind of Polymorphism, that I am use to in other projects (where we have been using raw SQL).

The C# Model would look like this:

public class Booking
{
    public int BookingID { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    public IRessource Ressources { get; set; }
    ...
}

public interface IRessource
{
    public int RessourceTypeId { get; set; }
}

public class Room : IRessource
{
    public int RoomID { get; set; }
    public int RessourceTypeId { get; set; }
    ...
}

public class Car : IRessource
{
    public int CarID { get; set; }
    public int RessourceTypeId { get; set; }
    ...
}

Is this achievable, and if yes, then how? How would the querying even look?

解决方案

Yes, absolutely.

It sounds like you really want a Table Per Type (TPT) relationship. This represents the standard is-a / has-a foreign key relationships. Note that by default, Entity Framework utilizes Table Per Hierarchy (TPH).

Here are some links:

I highly recommend you go through some of these links on your own, but the main point to extract is that you use something like:

modelBuilder.Entity<IRessource>().ToTable("IRessources");
modelBuilder.Entity<Room>().ToTable("Rooms");
modelBuilder.Entity<Car>().ToTable("Cars");

Both of which inherit from IRessource in your demonstrated code above. Then, you can do a join between these individual tables and the central IRessource table to get all of the information pertaining to the individual entities.

Something like: SELECT * FROM IRessource i JOIN Room r ON i.id == r.id

However, you'll often times find that if you use a Web API controller, if you just pull the entire Room POCO, you'll get all of its properties at once without the join at all!


In my experience, I've also found that typically things go smoother if you do not use interfaces or abstract classes because if you do, you'll have to make Data Transfer Objects (DTOs) to transfer data occasionally since you can't instantiate objects of those types. Things can get a little bit messy -- especially if you're not sure exactly what you're doing. To help you understand, think of a controller with which you want to pass in a generic IRressource -- it'll try to convert those objects as it receives them into one which can't be instantiated. Bummer! So, the easy solution is just to make both the base class and the inherited classes normal classes.

这篇关于实体框架多态关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆