簡體   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