繁体   English   中英

MySql 上的实体框架核心调用 FromSqlInterpolated 并返回实体列表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM