在EF Core 2.1中的DbContext上执行RAW SQL

时间:2018-11-28 10:39:46

标签: c# sql entity-framework ef-core-2.1

我有researched this,并且总是找到这样的示例:

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

问题是,我不想在Blogs表上运行原始SQL。基本上,我想实现这样的接口:

bool ExecuteNonSafeSql(
    string connectionString,
    string sql);

是否可以使用DbContext做到这一点?

3 个答案:

答案 0 :(得分:5)

在撰写本文时(EF Core 2.1),无法执行任意的安全性返回 SQL命令。

通过FromSql仅支持实体类型和Query Types

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

class ResultType
{
   // ...
}

然后

modelBuilder.Query<ResultType>();

最后

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

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

答案 1 :(得分:2)

您可以使用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))

答案 2 :(得分: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");