包括实体框架TPH类的导航属性 [英] Including navigation properties from Entity Framework TPH classes

查看:152
本文介绍了包括实体框架TPH类的导航属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个EF层次结构(大大简化了)看起来像这样:

I've got an EF hierarchy that (dramatically simplified) looks something like this:

class Room { EntityCollection<Session> Sessions; }
class Session { EntityCollection<Whiteboard> Whiteboards; EntityReference Room; }
class Whiteboard { EntityCollection<WhiteboardShape> WhiteboardShapes; EntityReference Session; }
abstract class WhiteboardShape { EntityReference Whiteboard; }
class WhiteboardShapeEllipse : WhiteboardShape { }
class WhiteboardShapePolyline { WhiteboardShape { EntityCollection<PolylinePoint> PolylinePoints }
class PolylinePoint { EntityReference<WhiteboardShapePolyline> WhiteboardShapePolylineReference; }

换句话说,一个房间可以包含多个会话;每个会话可以包含多个白板;并且每个白板可以包含多个白板形状。这些形状可以是各种类型的,包括一个WhiteboardShapePolyline,它本身可以包含多个PolylinePoints。

In other words, a Room can contain multiple sessions; each Session can contain multiple Whiteboards; and each Whiteboard can contain multiple WhiteboardShapes. These shapes can be of various types, including a WhiteboardShapePolyline, which itself can contain multiple PolylinePoints.

当远程用户最初连接到房间时,我需要传递整个对象图表,我正在试图找出如何尽可能高效地将图形从数据库加载到内存中。

When a remote user initially connects to the room, I need to pass the entire object graph to that user, and I'm trying to figure out how to load that graph from the database into memory as efficiently as possible.

现在,当然, EF允许您进行热切加载,如下所示:

Now, of course, the EF allows for you to do eager loading, like so:

      Room room = ctx.Room
            .Include("Sessions.Whiteboards")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

但是Include()不让我加载PolylinePoints。具体来说,如果我尝试:

But Include() doesn't let me load up the PolylinePoints. Specifically, if I try:

        Room room = ctx.Room
            .Include("Sessions.Whiteboards.WhiteboardShape.PolylinePoint")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

我得到异常指定的包含路径无效EntityType'SlideLinc.Model.WhiteboardShape '没有声明一个名为'PolylinePoint'的导航属性。

I get the exception "A specified Include path is not valid. The EntityType 'SlideLinc.Model.WhiteboardShape' does not declare a navigation property with the name 'PolylinePoint'."

也没有这样做:

.Include("Sessions.Whiteboards.WhiteboardShapePolyline.PolylinePoint")

也没有这样:

.Include("Sessions.Whiteboards.WhiteboardShape.WhiteboardShapePolyline.PolylinePoint")

也没有任何其他方式来构建我可以想到的导航路径。

Nor any other way of framing the navigation path that I can think of.

我最终做的一切确定<我似乎对我一个黑客:

The way that I've ended up doing it sure seems like a hack to me:

        // Make sure we've got everything loaded.
        if (room != null)
        {
            if (!room.Sessions.IsLoaded) { room.Sessions.Load(); }
            foreach (Session session in room.Sessions)
            {
                if (!session.Whiteboards.IsLoaded) { session.Whiteboards.Load(); }
                foreach (Whiteboard whiteboard in session.Whiteboards)
                {
                    if (!whiteboard.WhiteboardShape.IsLoaded) { whiteboard.WhiteboardShape.Load(); }
                    foreach (WhiteboardShape shape in whiteboard.WhiteboardShape)
                    {
                        if (shape is WhiteboardShapePolyline)
                        {
                            WhiteboardShapePolyline polyline = (WhiteboardShapePolyline)shape;
                            if (!polyline.PolylinePoints.IsLoaded) { polyline.PolylinePoints.Load(); }
                        }
                    }
                }
            }
        }

它的工作原理,但它比我想要的代码要多得多,而且它比我想要的更多的数据库访问。

It works, but it's a lot more code than I want, and it's a whole bunch more database accesses than I want.

我找到的最接近的答案是这里,但我可怜的Linq饥饿的大脑无法弄清楚如何将示例代码翻译成我所拥有的更复杂的层次结构;加上,该链接的示例代码是丑陋的,难以理解。我不希望我的整个对象层次结构取决于EF内部如何构建其层次结构的模糊和隐形的副作用。

The closest answer I've found is here, but my poor Linq-starved brain can't figure out how to translate the example code into the more complicated hierarchy that I've got; plus, the sample code at that link is damned ugly and difficult to understand. I don't really want my entire object hierarchy depending on an obscure and invisible side-effect of how the EF internally constructs its hierarchies.

任何其他建议?

推荐答案

我可能会用这个投影。而不是返回实体类型,而是将其投影到轻量级数据传输对象或匿名类型上。当您投影(例如,使用LINQ查询)时,会自动加载。您不需要在这种情况下指定Include。

I would probably use projection for this. Instead of returning entity types, project onto lightweight data transfer objects or anonymous types. When you project (e.g., with a LINQ query), the loading happens automatically. You don't need to specify an Include in this case.

这篇关于包括实体框架TPH类的导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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