无dbset的原始sql查询-实体框架核心

4xrmg8kj  于 2021-07-24  发布在  Java
关注(0)|答案(18)|浏览(481)

移除实体框架核心 dbData.Database.SqlQuery<SomeModel> 我找不到为全文搜索查询构建原始sql查询的解决方案,该查询将返回表数据和秩。
我见过的在实体框架核心中构建原始sql查询的唯一方法是通过 dbData.Product.FromSql("SQL SCRIPT"); 这是没有用的,因为我没有dbsetMap我在查询中返回的秩。
有什么想法吗???

avwztpqn

avwztpqn16#

目前,在efcore有新功能之前,我会使用命令并手动Map它

using (var command = this.DbContext.Database.GetDbConnection().CreateCommand())
  {
      command.CommandText = "SELECT ... WHERE ...> @p1)";
      command.CommandType = CommandType.Text;
      var parameter = new SqlParameter("@p1",...);
      command.Parameters.Add(parameter);

      this.DbContext.Database.OpenConnection();

      using (var result = command.ExecuteReader())
      {
         while (result.Read())
         {
            .... // Map to your entity
         }
      }
  }

尝试使用sqlparameter来避免sql注入。

dbData.Product.FromSql("SQL SCRIPT");

fromsql不适用于完整查询。例如,如果您想包含where子句,它将被忽略。
一些链接:
使用实体框架核心执行原始sql查询
原始sql查询

pexxcrt2

pexxcrt217#

在efcore中,您不能再执行“free”原始sql。您需要定义一个poco类和一个 DbSet 为了那个班。在您的情况下,您需要定义等级:

var ranks = DbContext.Ranks
   .FromSql("SQL_SCRIPT OR STORED_PROCEDURE @p0,@p1,...etc", parameters)
   .AsNoTracking().ToList();

因为它肯定是只读的,所以包含 .AsNoTracking() 打电话。
编辑-ef core 3.0中的突破性变化:
dbquery()现在已经过时,应该(再次)使用dbset()。如果您有一个无键实体,即它不需要主键,则可以使用hasnokey()方法:

ModelBuilder.Entity<SomeModel>().HasNoKey()

更多信息可以在这里找到

k2arahey

k2arahey18#

在其他答案的基础上,我编写了这个帮助程序来完成任务,包括示例用法:

public static class Helper
{
    public static List<T> RawSqlQuery<T>(string query, Func<DbDataReader, T> map)
    {
        using (var context = new DbContext())
        {
            using (var command = context.Database.GetDbConnection().CreateCommand())
            {
                command.CommandText = query;
                command.CommandType = CommandType.Text;

                context.Database.OpenConnection();

                using (var result = command.ExecuteReader())
                {
                    var entities = new List<T>();

                    while (result.Read())
                    {
                        entities.Add(map(result));
                    }

                    return entities;
                }
            }
        }
    }

用法:

public class TopUser
{
    public string Name { get; set; }

    public int Count { get; set; }
}

var result = Helper.RawSqlQuery(
    "SELECT TOP 10 Name, COUNT(*) FROM Users U"
    + " INNER JOIN Signups S ON U.UserId = S.UserId"
    + " GROUP BY U.Name ORDER BY COUNT(*) DESC",
    x => new TopUser { Name = (string)x[0], Count = (int)x[1] });

result.ForEach(x => Console.WriteLine($"{x.Name,-25}{x.Count}"));

我计划在添加了内置支持后立即将其删除。根据来自ef核心团队的arthur vickers的一份声明,这是2.0后的一个高度优先事项。这个问题正在这里追踪。

相关问题