zoukankan      html  css  js  c++  java
  • Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:继承查询

    继承引入了多态查询的概念。这种类型的查询认为继承层次结构和返回的对象可能是不同类型,但是继承自相同的基类。

    假设你想查询所有的产品。从多态查询获得的是Product对象列表,但具体的类型是Shirt或者Shoe,因为引擎自动实例化为正确的类型。你不仅可以自动得到正确的类型,还可以根据类型应用过滤。例如,你可以只查询鞋子或者只查询衬衫。

    我们敬爱的beta测试用户终于对OrderIT订单的展示满意了,现在用户想把注意力放在产品上。首先,他们想在单页中查看所有的产品。这非常简单:

    var result = from p in ctx.Products
                 select p;

    这段代码的结果是Product对象的列表,但是真实的类型是它具体的继承类。

    接下来用户想根据产品的类型应用筛选。LINQ提供两种方式指定类型:类型相等运算符(is)和OfType方法。这两种方法有一个重要的区别。相等运算符执行筛选操作,然而OfType<T>方法不仅筛选,还转换为需要查询的类型。下面的代码更清楚:

    IEnumerable<Product> products = from p in ctx.Products
                                    where p is Shoe
                                    select p;
    IEnumerable<Shoe> shoes = from p in ctx.Products.OfType<Shoe>()
                              select p;

    由于这种微小的差别,选择哪种方法完全是个人问题。假设你有几个产品类型,你需要找到唯一的鞋和衬衫。

    在这个例子中,使用OfType<T>是可能的,但是太复杂,因为你必须合并两个查询来检索不同的对象。合并结果之前,你必须转换内在对象成Product基类。相比之下,相等运算符不需要修改最后的结果,所以过滤后你不需要做额外的工作。

    在其他情况下,你可能想只搜索一个具体的产品。在种情况下,使用OfType<T>方法是最好的选择。

    对基类的属性筛选可以使用同样的方式。用户现在想对继承类型的数据筛选,例如,用户需要所有Sport属性包含Basket的鞋子。这是另一个适用OfType<T>的情况。因为OfType<T>转换数据,where方法(放在OfType<T>方法之后)已经知道输出类型是Shoe,所以这个搜索非常简单:

    var result = from p in ctx.Products.OfType<Shoe>()
                 where p.Sport == "Basket"
                 select p;

    但是如果你想找到所有的“basket”的鞋子而且以列表的方式返回Product对象呢?这种情况,前面的代码就不起作用了,因为它返回Shoe对象的列表。有两个解决方法:使用LINQ的Cast<T>方法,它转换回Product,或者在Where子句中转换Object成所需的类型,然后应用筛选。第二种,不能使用显示转换,那将导致一个运行时异常。你必须采用as转换操作符。

    第一种的代码:

    var result = from p in ctx.Products
                 where (p as Shoe).Sport == "Basket"
                 select p;

    第二种代码:

    var result = (from p in ctx.Products.OfType<Shoe>()
                  where p.Sport == "Basket"
                  select p).Cast<Product>();

    第一种方法,所需的类型是Product,所以所有的产品被扫描但是只有“Basket”的鞋子返回。生成的SQL也是按照相同的途径:它扫描所有的Product,Shoe和Shirt表,使用select case SQL子句识别一行是shoe还是shirt,浪费了很多资源,因为你不需要从Shirt表中获取数据。

    第二种方法,因为它直接规定了所需的类型是Shoe,生成的SQL只是用Product和Shoe表,优化了查询性能。除非你有强大的动力在Where中使用转换,否则最好始终使用OfType<T>方法。

    还有另一个性能说明要铭记于心。考虑下面的代码:

    var result = from p in ctx.Products
                 select p.Name;

    所涉及的唯一列是Product表中的Name。你可能期望生成的SQL只查询那个表。但SQL在层次结构(Shirt和Shoe)上和涉及到的表执行外连接。这种情况下,存储过程是最好的方法。

    到目前为止,你已经使用了标准的LINQ方法。他们很强大,但它们不包括所有的查询可能性。LINQ to Entities允许你应用任何的CLR方法,但是SQL转换引擎并不能理解一切。更重要的是,你可能有一个数据库函数或者自定义函数在LINQ to Entities查询中很有用,但是没有办法使用这些函数。这就是EF4.0函数功能发挥作用的地方

  • 相关阅读:
    App更新之dialog数字进度条
    Android app启动是出现白屏或者黑屏如何解决?
    Tensorflow报错:AttributeError: module 'tensorflow._api.v1.io' has no attribute 'gfile'
    《Python深度学习》第三章阅读笔记
    在Ubuntu 18.04上配置CPU深度学习环境
    《Python深度学习》第二章阅读笔记
    《Python深度学习》第一章阅读笔记
    POJ 1118 Lining Up
    蓝桥杯-地宫取宝(动态规划)
    洛谷P2280[HNOI2003] 激光炸弹(二维前缀和)
  • 原文地址:https://www.cnblogs.com/nianming/p/2165836.html
Copyright © 2011-2022 走看看