Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当使用TPC时,实体框架代码如何首先从基类集中找到类型化实体_C#_Entity Framework_Code First - Fatal编程技术网

C# 当使用TPC时,实体框架代码如何首先从基类集中找到类型化实体

C# 当使用TPC时,实体框架代码如何首先从基类集中找到类型化实体,c#,entity-framework,code-first,C#,Entity Framework,Code First,所以这个问题听起来可能有点深奥,但我注意到了一些“神奇”的东西,我对引擎盖下发生的事情的表现感到担忧。假设我使用TPC设计创建实体,所有实体(直接或间接)继承自一个根基实体,并且根基实体包含一个全局唯一标识符(如Guid),该标识符在保存之前在代码中生成(即,不是由数据库生成) 我希望下面的代码能够通过查询与coorisponding泛型类型相关的表来返回类型化的动态代理(确实如此): context.Set().Find(someGuid) 但是,我也注意到我可以执行以下操作: context

所以这个问题听起来可能有点深奥,但我注意到了一些“神奇”的东西,我对引擎盖下发生的事情的表现感到担忧。假设我使用TPC设计创建实体,所有实体(直接或间接)继承自一个根基实体,并且根基实体包含一个全局唯一标识符(如Guid),该标识符在保存之前在代码中生成(即,不是由数据库生成)

我希望下面的代码能够通过查询与coorisponding泛型类型相关的表来返回类型化的动态代理(确实如此):

context.Set().Find(someGuid)

但是,我也注意到我可以执行以下操作:

context.Set().Find(someGuid)


这非常酷,它会神奇地返回一个类型化的动态代理,用于正确的具体类的请求Id。EF究竟是如何知道Id属于哪个派生类/表的?它是否会查看它知道的每一个表/实体类型,直到找到匹配项为止(因此性能问题)?

继承表/实体的主键也是指向基表的外键

然后它需要做的就是查看从基类继承的类。它可能也会在加载时将关系缓存在内存中的某个位置,以避免每次调用时反射的性能影响,因为该关系是运行时静态的

剩下的就是查询与子类名称匹配的表。这将是一个聚集索引搜索,因为需要继承。因此,虽然存在性能损失,但考虑到您获得的抽象,这是无关紧要的

编辑:

默认情况下,代码首先求助于每个层次结构的表(TPH),这是一个非规范化的表,在
描述符列中编码了一个实体类型。在这种情况下,该列告诉EF将结果类型转换为哪个实体


上面提到的TPC需要DBContext中的附加代码来指定正确的表映射。它可能会将其缓存在内存中,并运行上面描述的例程。

有点相关?-可能在执行Set.Find()时,它正在对所有可能的派生类型/表使用联合进行查询。。。有人能证实这一点吗?这篇文章应该可以帮助你:你可以使用SQL Profiler找到答案。正如Julie Lerman在@ckal的链接中所说:“我教过朋友、亲人和开发人员要避免的继承层次结构。”是的。EF查看每个表,生成的查询看起来非常可怕。这是对继承的不当使用。不仅因为查询,而且(主要!)因为OO原则。它从一开始就违反了Liskov。“它会检查它知道的每一个表/实体类型,直到找到一个匹配项(因此性能问题)”我的回答是:是的。我说不要因为没人知道你是否意识到这些问题就这么做,如果你没有意识到,那就太糟糕了。这就是评论的目的,这就是为什么我没有把它作为一个答案。