目录:
- EF Core提供的执行SQL语句的方法
- 自己封装SqlQuery方法,执行SQL语句
一.EF Core提供的执行SQL语句的方法
基于原始SQL查询创建LINQ查询,
FromSql
方法的返回类型只有IQueryable<T>
。
SqlParameter parameter = new SqlParameter("Id", 1);
User user = context.Set<User>("select * from User where Id=@Id", parameter).Single();
对数据库执行给定的SQL并返回受影响的行数。需要引用
Microsoft.EntityFrameworkCore
命名空间。
SqlParameter[] parameters = new []{
new SqlParameter("Id", 1),
new SqlParameter("Name", "zhansan")
};
context.Database.ExecuteSqlCommand("update User set Name=@Name where Id=@Id", parameters);
二.自己封装SqlQuery方法,执行SQL语句
但在EF Core(本篇文章使用的EF Core版本为2.2.1)
提供的的执行SQL语句的方法发现许多问题,比如:
- 不支持返回特定的泛型类型的元素
- 执行SQL查询语句查询某张表时查询返回的字段必须是该表的所有字段
所以根据上述问题,需要自己封装执行Sql语句查询的方法。
public static class EntityFrameworkCoreExtensions
{
private static DbCommand CreateCommand(DatabaseFacade facade, string sql, out DbConnection connection, params object[] parameters)
{
var conn = facade.GetDbConnection();
connection = conn;
conn.Open();
var cmd = conn.CreateCommand();
if (facade.IsSqlServer())
{
cmd.CommandText = sql;
cmd.Parameters.AddRange(parameters);
}
return cmd;
}
public static DataTable SqlQuery(this DatabaseFacade facade, string sql, params object[] parameters)
{
var command = CreateCommand(facade, sql, out DbConnection conn, parameters);
var reader = command.ExecuteReader();
var dt = new DataTable();
dt.Load(reader);
reader.Close();
conn.Close();
return dt;
}
public static List<T> SqlQuery<T>(this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new()
{
var dt = SqlQuery(facade, sql, parameters);
return dt.ToList<T>();
}
public static List<T> ToList<T>(this DataTable dt) where T : class, new()
{
var propertyInfos = typeof(T).GetProperties();
var list = new List<T>();
foreach (DataRow row in dt.Rows)
{
var t = new T();
foreach (PropertyInfo p in propertyInfos)
{
if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
p.SetValue(t, row[p.Name], null);
}
list.Add(t);
}
return list;
}
}
使用:
var context = new DbContext();
var userInfo = context.Database.SqlQuery<UserInfo>("select * from user");