• Entity Framework 4.1 and Poco 使用存储过程联表查询


    一:数据库支持

    为了演示本例,我们创建了另外一个简单的示例数据库MiniNW,该数据库来自于ADO.NET Entity Framework Extensions,但在本例中,我们不会使用这个针对EF的扩展框架,因为它对POCO的支持不好,同时它也不支持DbContext,简单的说来就是它目前不支持EF4.1。

    MiniNW可以在本示例代码的如下位置获得:

    image

    数据库对应关系如下(由于数据库相对简单,所以直接列出数据,从数据可以直观看出两表的关系):

    image

    二:生成POCO及DbContext

    我们使用Entity Framework Power Tools CTP生成POCO及相关映射,如果你对此不熟悉,可参考本篇《使用Entity Framework和WCF Ria Services开发SilverLight之3:Map》。

    三:主表从表数据一起关联查询

    数据库中存在存储过程GetCategory:

    ALTER proc [dbo].[GetCategory]
        @cid int
    as
    begin
        select *
        from Categories
        where @cid = cid
    end

    执行此存储过程的代码如下:

            public IEnumerable<Category> GetCategoryWithProductsWithID(int id)
            {
                var parameter = new SqlParameter
                {
                    DbType = DbType.Int32,
                    ParameterName = "cid",
                    Value = id
                };
                //联表并延迟加载
                var result = (from p in this.Categories.SqlQuery("EXECUTE GetCategory @cid", parameter) select p).ToList();
                return result;
            }

    得到的数据如下:

    image

    其中,Category所对应Products是延迟加载进来的,如果我们只使用Category,数据引擎就不会查询Products表的数据,但是,只要我们一到Category中查看Products,就会获取如上图这样的Products数据。请根据源码中的两个数据实体理解。

    执行存储部分的代码EF为我们生成如下:

    exec sp_executesql N'EXECUTE GetCategory @cid',N'@cid int',@cid=1

    延迟加载部分的代码EF为我们生成如下:

    exec sp_executesql N'SELECT 
    [Extent1].[pid] AS [pid], 
    [Extent1].[name] AS [name], 
    [Extent1].[discontinued_date] AS [discontinued_date], 
    [Extent1].[cid] AS [cid]
    FROM [dbo].[Products] AS [Extent1]
    WHERE [Extent1].[cid] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1

    三:仅获取主表数据

    如果不需要关联表的数据,我们可以像下面这样编码。以下这段代码使用的是和上文一样的存储过程:

            public IEnumerable<Category> GetCategoryWithID(int id)
            {
                var parameter = new SqlParameter
                {
                    DbType = DbType.Int32,
                    ParameterName = "cid",
                    Value = id
                };
                //非联表
                var result = (from p in this.Categories.SqlQuery("EXECUTE GetCategory @cid", parameter)
                              select new
                              {
                                  cid = p.cid,
                                  name = p.name
                              }).ToList()
                             .Select(r => new Category()
                             {
                                 cid = r.cid,
                                 name = r.name
                             });
                return result;
            }

    如果你对这段代码表示不很理解,请参看此文《使用Entity Framework和WCF Ria Services开发SilverLight之6:查找指定字段》。

    获取数据如下:

    image

    四:由从表关联主表数据

    从表关联主表的存储过程如下:

    ALTER proc [dbo].[GetProductAndCategory]
        @pid int
    as
    begin
        select p.pid, p.[name] , p.discontinued_date, c.cid, c.[name] 
        from Products as p join Categories as c on p.cid = c.cid
        where p.pid = @pid    
    end

    注意,原始例子所带的存储过程不是这样的,多了这样的语句:

    image

    DbContext默认支持实体类型的字段和数据库视图是一个字段名,所以我们去掉了重命名部分。

    实现此功能的代码如下:

            public IEnumerable<Product> GetProductAndCategoryWithID(int id)
            {
                var parameter = new SqlParameter
                {
                    DbType = DbType.Int32,
                    ParameterName = "pid",
                    Value = id
                };
                //延迟加载
                var result = (from p in this.Products.SqlQuery("EXECUTE dbo.GetProductAndCategory @pid", parameter) select p).ToList();
                return result;
            }

    要注意,主表的数据也是延迟加载的,只有使用到的时候才会被查询。

    EF为我们生成的代码如下:

    exec sp_executesql N'EXECUTE dbo.GetProductAndCategory @pid',N'@pid int',@pid=1

    获取的数据如下:

    image

    源码下载:SLOperation20110703.zip

  • 相关阅读:
    [EffectiveC++]item22:Declare data members private
    垃圾人定律
    [EffectiveC++]item17:以独立语句将newed对象置入智能指针
    [EffectiveC++]item15:Provide access to raw resources in resource-managing class
    C++ 中operator用法:隐式类型转换
    [EffectiveC++]item13:Use objects to manage resources(RAII)
    为什么拷贝构造函数的参数必须是引用?
    SPF邮件服务器
    raspberry
    bash
  • 原文地址:https://www.cnblogs.com/luminji/p/2096896.html
Copyright © 2020-2023  润新知