Entity Framework 4.1 and Poco 使用存储过程联表查询
一:数据库支持
为了演示本例,我们创建了另外一个简单的示例数据库MiniNW,该数据库来自于ADO.NET Entity Framework Extensions,但在本例中,我们不会使用这个针对EF的扩展框架,因为它对POCO的支持不好,同时它也不支持DbContext,简单的说来就是它目前不支持EF4.1。
MiniNW可以在本示例代码的如下位置获得:
数据库对应关系如下(由于数据库相对简单,所以直接列出数据,从数据可以直观看出两表的关系):
二:生成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; } |
得到的数据如下:
其中,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:查找指定字段》。
获取数据如下:
四:由从表关联主表数据
从表关联主表的存储过程如下:
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 |
注意,原始例子所带的存储过程不是这样的,多了这样的语句:
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 |
获取的数据如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库