EF Core 自定义查询
如何使用 EF Core 可以参考之前的文章 【.NET Core】Entity Framework Core。
其中记录了 EF Core 中无法使用自定义查询的问题,而在 5 月 30 日 发布的 EF Core 2.1 中已经实现该功能(有意思的是上面那篇 bolg 是我 5 月 29 日 写的)。
下面的实现方法来自官方的 issue Raw store access APIs: Support for ad hoc mapping of arbitrary types
实现方法
在 DBContext 的
OnModelCreating
方法中添加modelBuilder.Query<YourModel>();
处理;csharpprotected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Query<YourModel>(); }
使用
Query<YourModel>().FromSql()
方法执行自定义查询;csharppublic async Task<List<YourModel>> GetYourModel(string value1, Nullable<decimal> value2) { SqlParameter value1Input = new SqlParameter("@Param1", value1?? (object)DBNull.Value); SqlParameter value2Input = new SqlParameter("@Param2", value2?? (object)DBNull.Value); List<YourModel> getYourModel = await this.Query<YourModel>().FromSql("STORED_PROCEDURE @Param1, @Param2", value1Input, value2Input).ToListAsync(); return getYourModel; }
查询 View
这种方法还可以用来查询 View 或 没有主键的表,如何查询 View 可以参考这篇官方的帮助文档 Query Types - EF Core _ Microsoft Docs。
下面是帮助文档上的示例代码:
表模型
cspublic class Blog { public int BlogId { get; set; } public string Name { get; set; } public string Url { get; set; } public ICollection<Post> Posts { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int BlogId { get; set; } }
创建视图
csdb.Database.ExecuteSqlCommand( @"CREATE VIEW View_BlogPostCounts AS SELECT Name, Count(p.PostId) as PostCount from Blogs b JOIN Posts p on p.BlogId = b.BlogId GROUP BY b.Name");
查询结果模型
cspublic class BlogPostsCount { public string BlogName { get; set; } public int PostCount { get; set; } }
在 OnModelCreating 中通过
modelBuilder.Query<T>
配置查询类型及映射。csprotected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder .Query<BlogPostsCount>().ToView("View_BlogPostCounts") .Property(v => v.BlogName).HasColumnName("Name"); }
查询数据库
csvar postCounts = db.BlogPostCounts.ToList(); foreach (var postCount in postCounts) { Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts."); Console.WriteLine(); }