Entity framework 使用实体框架和.net内核执行SP
我使用.NETCore和EntityFramework创建了一个WebAPI项目。 这使用了一个存储过程,它返回实体框架定义的数据库表的大部分属性 实体framwrok不会返回表中的所有列。当我调用api时,我得到一个错误,它抱怨当我使用Entity framework 使用实体框架和.net内核执行SP,entity-framework,asp.net-core,asp.net-core-webapi,Entity Framework,Asp.net Core,Asp.net Core Webapi,我使用.NETCore和EntityFramework创建了一个WebAPI项目。 这使用了一个存储过程,它返回实体框架定义的数据库表的大部分属性 实体framwrok不会返回表中的所有列。当我调用api时,我得到一个错误,它抱怨当我使用 _context.Set<TableFromSql>().FromSql("execute dbo.spr_GetValue").ToList(); 我创建了另一个模型类,它定义了从SP带回的名为NewClass的属性 _context.Set&
_context.Set<TableFromSql>().FromSql("execute dbo.spr_GetValue").ToList();
我创建了另一个模型类,它定义了从SP带回的名为NewClass的属性
_context.Set<NewClass>().FromSql("execute dbo.spr_GetValue").ToList();
这是可行的,但只是想检查是否存在SP只从数据库返回模型类的约定
SQL查询必须返回实体或查询类型的所有属性的数据
对于此限制,它是在将sql查询结果映射到模型时产生的。它循环遍历模型中的属性,并尝试从查询结果中检索值。如果查询结果中不存在模型属性,它将抛出错误
如果要返回所需的列而不是所有列,一个选项是通过查询定义返回的模型
对于您的演示代码,您可以在OnModelCreating中定义它
使用上述代码,如:
var result = _context.RawSqlQuery<ToDoItemVM>("execute [dbo].[get_TodoItem]");
看。它在限制下声明:SQL查询必须返回实体或查询类型的所有属性的数据。这是否意味着我不应该添加自己的模型类并更改SP以返回实体的所有属性。那个么,对于真正复杂的sql SP呢?它不需要返回整个列,可能是在数据库中的表之间使用连接?不,这并不是我的意思。EF Core自2.1以来有两种类型的模型:映射到数据库表的实体和Tau Zhou在回答中提到的查询类型。查询类型不映射到数据库表。从您的查询中,不太清楚TableFromSql是否是一个模型。但无论如何,上述限制同时适用于实体和查询类型。如果TableFromSql是一个实体,并且该过程只返回属性的子集,那么您应该使用查询类型来创建一个名为NewClass.cs的新模型类,如上所述,并将其添加到类似modelBuilder的context.cs中。Entityentity=>{entity.HasKeye=>e.LocationId;};这个很好用。但我只是想知道这样做是否是错误的?@liroforum这是从sp.builder返回自定义列的正确且当前推荐的方法。Query用于返回自定义模型。因此,我向modelBuilder添加了新类,如modelBuilder.Query;并在控制器中使用它,如_context.Query.FromSqlexecute dbo.spr_GetValue.ToList。这是对的还是你的意思是别的?是否可以像中那样从context.cs调用sql SP?谢谢Tao,这很有帮助。
public static class DbContextExtensions
{
public static List<T> RawSqlQuery<T>(this DbContext context,string query)
{
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>();
return DataReaderMapToList<T>(result);
}
}
}
public static List<T> DataReaderMapToList<T>(IDataReader dr)
{
List<T> list = new List<T>();
T obj = default(T);
while (dr.Read())
{
obj = Activator.CreateInstance<T>();
foreach (PropertyInfo prop in obj.GetType().GetProperties())
{
if (ColumnExists(dr, prop.Name))
{
if (!object.Equals(dr[prop.Name], DBNull.Value))
{
prop.SetValue(obj, dr[prop.Name], null);
}
}
}
list.Add(obj);
}
return list;
}
public static bool ColumnExists(IDataReader reader, string columnName)
{
return reader.GetSchemaTable()
.Rows
.OfType<DataRow>()
.Any(row => row["ColumnName"].ToString() == columnName);
}
}
var result = _context.RawSqlQuery<ToDoItemVM>("execute [dbo].[get_TodoItem]");