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:

?
1
2
3
4
5
6
7
8
ALTER proc [dbo].[GetCategory]
     @cid int
as
begin
     select *
     from Categories
     where @cid = cid
end

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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为我们生成如下:

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

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

?
1
2
3
4
5
6
7
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

三:仅获取主表数据

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

四:由从表关联主表数据

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

?
1
2
3
4
5
6
7
8
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默认支持实体类型的字段和数据库视图是一个字段名,所以我们去掉了重命名部分。

实现此功能的代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
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为我们生成的代码如下:

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

获取的数据如下:

image

源码下载:SLOperation20110703.zip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值