postgresql - 如何使用需要返回行的 EF Core 执行原始 sql 插入查询?
问题描述
我使用 EF Core for PostgreSQL,如此处所述。我想执行一些返回行的原始 sql 查询。
最简单的是这个(它可能看起来很奇怪,因为它返回的正是插入的内容,但它很简单,可以用作示例):
INSERT INTO public."TodoItems" ("Id", "Todo") VALUES ('915714b6-1c67-444d-8106-d778fcb4bb1a', 'Hi') RETURNING "Id", "Todo"
这是我的上下文类:
public class DoContext : DbContext
{
public DoContext(DbContextOptions<DoContext> options) : base(options)
{
Console.WriteLine("Context created");
}
public DbSet<TodoItem> TodoItems { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
Console.WriteLine("OnModelCreating");
}
}
这是实体类。
public class TodoItem
{
public Guid Id { get; set; }
public string Todo { get; set; }
}
这是我执行查询的代码:
string query = "INSERT INTO public.\"TodoItems\" (\"Id\", \"Todo\") VALUES ('915714b6-1c67-444d-8106-d778fcb4bb1a', 'Hi') RETURNING \"Id\", \"Todo\"";
var result = context.TodoItems.FromSqlRaw(query).First();
我的查询很好。它在表为空并且查询在 DataGrip 中执行时工作。但是,在运行我的代码时,最后一行会导致以下异常:
Npgsql.PostgresException 42601:“INTO”处或附近的语法错误
我从文档中了解到,FromSqlRaw 是预期返回行时使用的正确方法。但是,此方法似乎无法理解我的(经过测试且有效的)查询。
那么如何使用 EF 核心执行这个查询呢?这里重要的是我真的要使用 EF Core,因为我需要 sql 世界和我拥有的实体之间的映射。我使用.NET 5。
解决方案
避免使用类似First
和类似的查询限制运算符,因为 EF Core 将尝试组合提供的 SQL - 基本上将其包装在外部SELECT
(SELECT * FROM (Your_SQL)
为了应用TOP N
或类似的运算符。这会导致无效的 SQL 语法。
所以它可能看起来很奇怪,但是使用物化运算符代替 - ToList()
,ToArray()
或者AsEnumerable()
在此时停止IQueryable
处理并执行数据库查询,例如
var result = context.TodoItems.FromSqlRaw(query)
.AsEnumerable() // <-- database query ends here
.First(); // <-- this runs in LINQ to Objects context
推荐阅读
- twitter - Twitter 广告 API:twitter_ads.error.RateLimit
- javascript - 单击另一个无线电输入后更改变量的值
- java - 如何在特定事件期间更改 KeyListener 执行的操作
- mysql - 如何重构超过 30 列的旧表
- c - 在C中对指针数组进行排序
- c# - Xamarin Post Json 数据错误(不允许使用 405 方法)
- reactjs - 不允许在 draft-js-mention-plugin 中多次提及
- angular - @teamhive/ngx-tooltip 不确定如何以编程方式显示()工具提示
- react-native - 如何使用缩放 SDK 减小 react-native 中的 APK 大小?
- javascript - 修复我的函数以使用附加的 Million, Billion, Thousandth 字符串转换大整数更具可读性