在EF Core 2.1中在DbContext上执行原始SQL

6

我已经研究过,并且总是发现像这样的例子:

var blogs = context.Blogs
    .FromSql("SELECT * FROM dbo.Blogs")
    .ToList();

问题在于,我不想在Blogs表上运行我的原始SQL。基本上,我想要实现这样一个接口:
bool ExecuteNonSafeSql(
    string connectionString,
    string sql);

有没有使用DbContext的方法可以做到这一点?


您可以使用 context.Database 的方法,例如 context.Database.ExecuteSqlCommand()context.Database.SqlQuery()。使用哪种方法取决于您想要做什么。您的语句将返回什么值? - NineBerry
如果命令成功执行,则返回“true”。否则返回“false”。 - J86
你说的“成功”是什么意思?能给个例子吗? - NineBerry
在MySQL Workbench中,如果我运行一个查询(无论它是选择还是插入),我会看到一个绿色的对勾,告诉我操作成功,并且有x行受影响。所以我想知道有没有类似绿色对勾的等效符号? - J86
3个回答

10

您可以使用 context.Database.ExecuteSqlCommand() 来执行 SQL。

如果您想使用 SqlCommand,可以通过以下方式获取连接:

var cnn = (SqlConnection) context.Database.GetDbConnection();
cnn.Open();
using (var cmd = new SqlCommand(sql, cnn))
using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleResult))

ExecuteSqlCommand将返回受影响的记录数。当语句无法执行时,它会抛出异常。 - NineBerry

7

在撰写本文时(EF Core 2.1),没有办法执行任意的返回序列的SQL命令。

只有实体类型和查询类型可以通过FromSql支持。

因此,最接近的解决方案是定义查询类型(保存查询结果的类)并使用FromSql,但它不是通用的 - 查询类型必须通过流畅的API在DbContext中注册,并且该方法应该接收指定该类型的通用参数,例如

class ResultType
{
   // ...
}

那么

modelBuilder.Query<ResultType>();

最后

db.Query<ResultType>().FromSql(...)

请注意,Database.ExecuteSqlCommand可以执行任意SQL语句,但不能用于返回序列(IEnumerable<T>, IQueryable<T>)。

我可以使用.ExecuteSqlCommand运行类似于DROP DATABASE IF EXISTS {databaseName};这样的命令吗? - J86
@J86 我认为你可以。任何标量 DDL、T-SQL、SP、批处理等命令都可以。只是你不能从包含/返回 SELECT … 的 SP/function/batch 中获取结果。 - Ivan Stoev

2

您可以直接使用Database.SqlQuery()函数在上下文中执行查询。

这里我创建了一个通用函数,可以直接在数据库中执行您的查询,而不是实体。

public static List<T> Execute<T>(MyDbContext context, string query) where T : class
{
    var result = context.Database
                        .SqlQuery<T>(query)
                        .ToList();

    return result;
}

您可以像使用以下函数一样使用上述函数:
var blogs = Execute<Blog>(context, "SELECT * FROM dbo.Blogs");

1
有 EF Core 的任何示例吗? - Olorunfemi Davis
@OlorunfemiAjibulu,目前我没有找到任何解决方案。但是这个链接可能是您想要的内容:https://www.learnentityframeworkcore.com/raw-sql#database.executesqlcommand - er-sho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接