问题
I have researched this and always found examples like this:
var blogs = context.Blogs
.FromSql("SELECT * FROM dbo.Blogs")
.ToList();
The problem is, I don't want to run my raw SQL on the Blogs table. Basically, I want to implement an interface like this:
bool ExecuteNonSafeSql(
string connectionString,
string sql);
Is there a way to do that with DbContext?
回答1:
At the time of writing (EF Core 2.1), there is no way to execute arbitrary secuence returning SQL command.
Only entity types and Query Types are supported via FromSql
.
So the closest solution is to define query type (a class holding the query result) and use FromSql
, but it's not generic - the query types must be registered in the DbContext
via fluent API and the method should receive a generic argument specifying that type, e.g
class ResultType
{
// ...
}
then
modelBuilder.Query<ResultType>();
and finally
db.Query<ResultType>().FromSql(...)
Note that Database.ExecuteSqlCommand
can execute arbitrary SQL, but can't be used to return sequence (IEnumerable<T>
, IQueryable<T>
).
回答2:
You can use context.Database.ExecuteSqlCommand()
to execute sql.
If you want to use SqlCommand
you can get the connection by
var cnn = (SqlConnection) context.Database.GetDbConnection();
cnn.Open();
using (var cmd = new SqlCommand(sql, cnn))
using (var rdr = cmd.ExecuteReader(CommandBehavior.SingleResult))
回答3:
You can use Database.SqlQuery()
directly to context.
Here i create a generic function that can execute your query directly with target to Database rather than entity.
public static List<T> Execute<T>(MyDbContext context, string query) where T : class
{
var result = context.Database
.SqlQuery<T>(query)
.ToList();
return result;
}
You can use above function like
var blogs = Execute<Blog>(context, "SELECT * FROM dbo.Blogs");
来源:https://stackoverflow.com/questions/53517493/execute-raw-sql-on-dbcontext-in-ef-core-2-1