您的数据库提供商本身不支持“SqlQuery”方法中的错误

Thi*_*tti 11 .net c# sql-server entity-framework-core ef-core-7.0

在 dbContext.Database.SqlQuery<T> 的函数执行调用中出现以下异常:

“您的数据库提供程序本身不支持“SqlQuery”方法中使用的元素类型“MyEntity”。使用受支持的元素类型,或使用 ModelConfigurationBuilder.DefaultTypeMapping 为您的类型定义映射。

异常详情

源代码。

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Test
{
    public class Employee
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    public class EmployeeInfo
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
    }

    public class EmployeeDBContext : DbContext
    {
        public DbSet<Employee> Employees { get; set; }
        public EmployeeDBContext() { }
        public EmployeeDBContext(DbContextOptions<EmployeeDBContext> options)
            : base(options) { }

        protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
        {
            base.ConfigureConventions(configurationBuilder);

            //Action<TypeMappingConfigurationBuilder<EmployeeInfo>> actionEmployeeInfo = (buildAction) => { };
            //configurationBuilder.DefaultTypeMapping(actionEmployeeInfo);
            //Action<TypeMappingConfigurationBuilder> action = (buildAction) => { };
            //configurationBuilder.DefaultTypeMapping(typeof(EmployeeInfo), action);
            //configurationBuilder.DefaultTypeMapping(typeof(EmployeeInfo));
            configurationBuilder.DefaultTypeMapping<EmployeeInfo>();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer("Data source=localhost;Database=EmployeeDB;User Id=sa;Password=Dev.NET;");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Employee>(builder => builder.HasKey(x => x.Id));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试代码。

using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using NUnit.Framework;

namespace Test
{
    [TestFixture]
    public class EmployeeTest
    {
        [Test(Description = nameof(Find_Employee_ReturnModel))]
        public void Find_Employee_ReturnModel()
        {
            // Arrange
            var dbContext = new EmployeeDBContext();
            dbContext.Database.EnsureDeleted();
            dbContext!.Database.EnsureCreated();

            var employee = new Employee { FirstName = "Joao", LastName = "Gomes" };
            dbContext.Employees.Add(employee);
            dbContext.SaveChanges();

            // Act
            var employeeInfo = dbContext.Database.SqlQuery<EmployeeInfo>($"SELECT e.Id as EmployeeId, e.FirstName as Name FROM Employee e").ToList();

            // Assert
            employeeInfo.Should().HaveCount(1);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

添加了推荐设置以返回数据库提供程序本身不支持的类型。

默认类型映射

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
        {
            base.ConfigureConventions(configurationBuilder);

            //Action<TypeMappingConfigurationBuilder<EmployeeInfo>> actionEmployeeInfo = (buildAction) => { };
            //configurationBuilder.DefaultTypeMapping(actionEmployeeInfo);
            //Action<TypeMappingConfigurationBuilder> action = (buildAction) => { };
            //configurationBuilder.DefaultTypeMapping(typeof(EmployeeInfo), action);
            //configurationBuilder.DefaultTypeMapping(typeof(EmployeeInfo));
            configurationBuilder.DefaultTypeMapping<EmployeeInfo>();
        }
Run Code Online (Sandbox Code Playgroud)

kri*_*zzn 6

不完全是解决方案,而是 EF8 到来之前的解决方法:

statement += " for json path";
var asJson = string.Join("", _context.Database.SqlQueryRaw<string>(statement)); 
return System.Text.Json.JsonSerializer.Deserialize<TModel[]>(asJson);
Run Code Online (Sandbox Code Playgroud)


小智 6

 EmployeeDetail detail =  _dbContext.EmployeeDetail.FromSqlInterpolated($"exec [dbo].[SPName] @Id = {Id}").ToList();
Run Code Online (Sandbox Code Playgroud)

将模型添加到 DBContext

  public virtual DbSet<EmployeeDetail> EmployeeDetails{ get; set; }
Run Code Online (Sandbox Code Playgroud)

将 [Keyless] 添加到模型定义中

 [Keyless]
public  class EmployeeDetail
{
    public int Name{ get; set; }
Run Code Online (Sandbox Code Playgroud)

  • EF 8/EF Core 中的最佳答案是什么 (2认同)