存储过程返回多个实体集
枚举的默认值,是基础类型的值为0对应的枚举值(如果没有对应的枚举值则默认值为0)
在使用NuGet安装实体框架时,migrate.exe位于下载包的tools文件夹中,在 <项目文件夹>\packages\EntityFramework.<版本>\tools 中
有了 migrate.exe 之后,需要将其复制到包含迁移的程序集位置。
ModeFist方式生成表结构时,在 EF 设计器中,右键单击模型上的空位置,选择“添加代码生成项...”,可以生成DbContext上下文
使用EF调用存储过程放回多个结果集
创建存储过程
CREATE PROCEDURE [dbo].[GetAllBlogsAndPosts]
AS
SELECT * FROM dbo.Blogs
SELECT * FROM dbo.Posts
默认情况下,这个存储过程只会返回Bogs的类型结果
解决方案:
方式一
1 using (var db = new BloggingContext()) 2 { 3 // If using Code First we need to make sure the model is built before we open the connection 4 // This isn't required for models created with the EF Designer 5 db.Database.Initialize(force: false); 6 7 // Create a SQL command to execute the sproc 8 var cmd = db.Database.Connection.CreateCommand(); 9 cmd.CommandText = "[dbo].[GetAllBlogsAndPosts]"; 10 11 try 12 { 13 14 db.Database.Connection.Open(); 15 // Run the sproc 16 var reader = cmd.ExecuteReader(); 17 18 // Read Blogs from the first result set 19 var blogs = ((IObjectContextAdapter)db) 20 .ObjectContext 21 .Translate<Blog>(reader, "Blogs", MergeOption.AppendOnly); 22 23 24 foreach (var item in blogs) 25 { 26 Console.WriteLine(item.Name); 27 } 28 29 // Move to second result set and read Posts 30 reader.NextResult(); 31 var posts = ((IObjectContextAdapter)db) 32 .ObjectContext 33 .Translate<Post>(reader, "Posts", MergeOption.AppendOnly); 34 35 36 foreach (var item in posts) 37 { 38 Console.WriteLine(item.Title); 39 } 40 } 41 finally 42 { 43 db.Database.Connection.Close(); 44 } 45 }
方式二
通过修改edmx文件文件,将存储过程对应返回的复杂类型修改为指定的实体类型(这种方式在更新模型后会在覆盖)
1.修改edmx对应的xml
1 <!-- CSDL content --> 2 <edmx:ConceptualModels> 3 4 ... 5 6 <FunctionImport Name="GetAllBlogsAndPosts" ReturnType="Collection(BlogModel.GetAllBlogsAndPosts_Result)" /> 7 8 ... 9 10 <ComplexType Name="GetAllBlogsAndPosts_Result"> 11 <Property Type="Int32" Name="BlogId" Nullable="false" /> 12 <Property Type="String" Name="Name" Nullable="false" MaxLength="255" /> 13 <Property Type="String" Name="Description" Nullable="true" /> 14 </ComplexType> 15 16 ... 17 18 </edmx:ConceptualModels> 19 20 修改成: 21 <FunctionImport Name="GetAllBlogsAndPosts"> 22 <ReturnType EntitySet="Blogs" Type="Collection(BlogModel.Blog)" /> 23 <ReturnType EntitySet="Posts" Type="Collection(BlogModel.Post)" /> 24 </FunctionImport> 25 26 27 <!-- C-S mapping content --> 28 <edmx:Mappings> 29 30 ... 31 32 <FunctionImportMapping FunctionImportName="GetAllBlogsAndPosts" FunctionName="BlogModel.Store.GetAllBlogsAndPosts"> 33 <ResultMapping> 34 <ComplexTypeMapping TypeName="BlogModel.GetAllBlogsAndPosts_Result"> 35 <ScalarProperty Name="BlogId" ColumnName="BlogId" /> 36 <ScalarProperty Name="Name" ColumnName="Name" /> 37 <ScalarProperty Name="Description" ColumnName="Description" /> 38 </ComplexTypeMapping> 39 </ResultMapping> 40 </FunctionImportMapping> 41 42 ... 43 44 </edmx:Mappings> 45 46 修改成: 47 <ResultMapping> 48 <EntityTypeMapping TypeName ="BlogModel.Blog"> 49 <ScalarProperty Name="BlogId" ColumnName="BlogId" /> 50 <ScalarProperty Name="Name" ColumnName="Name" /> 51 <ScalarProperty Name="Description" ColumnName="Description" /> 52 </EntityTypeMapping> 53 </ResultMapping> 54 <ResultMapping> 55 <EntityTypeMapping TypeName="BlogModel.Post"> 56 <ScalarProperty Name="BlogId" ColumnName="BlogId" /> 57 <ScalarProperty Name="PostId" ColumnName="PostId"/> 58 <ScalarProperty Name="Title" ColumnName="Title" /> 59 <ScalarProperty Name="Text" ColumnName="Text" /> 60 </EntityTypeMapping> 61 </ResultMapping>
2.执行如下代码
1 using (var db = new BlogEntities()) 2 { 3 var results = db.GetAllBlogsAndPosts(); 4 5 foreach (var result in results) 6 { 7 Console.WriteLine("Blog: " + result.Name); 8 } 9 10 var posts = results.GetNextResult<Post>(); 11 12 foreach (var result in posts) 13 { 14 Console.WriteLine("Post: " + result.Title); 15 } 16 17 Console.ReadLine(); 18 }
注意:这两种方式读取实体数据的顺序必须与存储过程中返回的实体顺序一致,否者会报错