Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 使用实体框架和.net内核执行SP_Entity Framework_Asp.net Core_Asp.net Core Webapi - Fatal编程技术网

Entity framework 使用实体框架和.net内核执行SP

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&

我使用.NETCore和EntityFramework创建了一个WebAPI项目。 这使用了一个存储过程,它返回实体框架定义的数据库表的大部分属性

实体framwrok不会返回表中的所有列。当我调用api时,我得到一个错误,它抱怨当我使用

_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]");