[英]Entity Framework Core on MySql calling FromSqlInterpolated and return list of entities
我在带有 Entity Framework Core 5.0.3 的 ASP Core 项目中使用 C#,并将 Pomelo EntityFrameworkCore 用于 MySql。
我可以使用以下方法调用标准 SP:
int recordCount = await context.Database.ExecuteSqlInterpolatedAsync($"call `SP_ON_MYSQL` ({param1}, {param2}");
有问题的 SP 输出我想要捕获的实体的结果集,当我尝试这个时:
var qry = await context.ENITY.FromSqlInterpolated($"call `SP_ON_MYSQL` ({param1}, {param2})").SingleOrDefaultAsync();
我收到以下错误:
*'FromSqlRaw' 或 'FromSqlInterpolated' 是用不可组合的 SQL 调用的,并且有一个查询在它上面进行组合。
提前感谢您提供的任何帮助。 考虑在客户端执行组合的方法之后调用“AsEnumerable”。*
我已经看到了与 SQL 服务器一起使用的示例,因此请不要标记为已回答,除非您可以向我展示一个不是 SQL 服务器特定的示例。
尝试这个:
var qry = await context.ENITY
.FromSqlInterpolated($"call `SP_ON_MYSQL` ({param1}, {param2})")
.ToListAsync()
.SingleOrDefault();
@Torvin 的答案是正确的。
如果您从存储过程中查询,则需要在SingleOrDefault()
调用之前添加AsEnumerable()
、 ToList()
等调用。 有关更多信息,请参阅官方 EF Core存储库的 FromSql #17558 中对不可组合的 SQL 重新引入检测。
这是一个完全工作的控制台程序,它演示了该方法:
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
namespace IssueConsoleTemplate
{
public sealed class IceCream
{
public int IceCreamId { get; set; }
public string Name { get; set; }
}
public class Context : DbContext
{
public DbSet<IceCream> IceCreams { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySql(
"server=127.0.0.1;port=3306;user=root;password=;database=So67040870",
b => b.ServerVersion("8.0.21-mysql")
.CharSetBehavior(CharSetBehavior.NeverAppend))
.UseLoggerFactory(
LoggerFactory.Create(
b => b
.AddConsole()
.AddFilter(level => level >= LogLevel.Information)))
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
}
}
internal class Program
{
private static void Main()
{
using var context = new Context();
SetupDatabase(context);
var iceCreamId = 1;
var searchContacts = context.IceCreams
.FromSqlInterpolated($"CALL `GetIceCreams`({iceCreamId})")
.AsEnumerable() // <-- Mandatory: Use AsEnumerable(), ToList() etc. or you will get an exception.
.SingleOrDefault();
Trace.Assert(searchContacts != null);
Trace.Assert(searchContacts.Name == "Vanilla");
}
private static void SetupDatabase(Context context)
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var connection = context.Database.GetDbConnection();
connection.Open();
using var command = connection.CreateCommand();
command.CommandText = @"CREATE PROCEDURE `GetIceCreams`(`someArg` int)
BEGIN
SELECT someArg as `IceCreamId`, 'Vanilla' as `Name`;
END";
command.ExecuteNonQuery();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.