使用FromSql和include时出错(“调用存储过程时不支持包含操作。”)

时间:2017-11-05 14:02:04

标签: c# sql asp.net-core ef-code-first ef-core-2.0

我使用了Asp.Net Core版本2并且代码优先。我尝试使用.FromSql来调用存储过程。我跟微软说的一样:

var blogs = context.Blogs
                   .FromSql($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
                   .Include(b => b.Posts)
                   .ToList();

我的存储过程只包含代码行

 ALTER PROCEDURE [dbo].[GetCouffierSearch]  
 AS
 BEGIN
     SET NOCOUNT ON;

     SELECT * 
     FROM AspNetUsers
END

我在API中的代码:

public IQueryable<ApplicationUser> SelectNearByUser()
{
    var query = "execute dbo.GetCouffierSearch";
    var res = _context.Users.FromSql(query);
    return res.Include(x => x.CoiffeurServiceLevels);
}

我的班级ApplicationUser包含CoiffeurServiceLevels类型为ICollection的定义:

public class ApplicationUser: IdentityUser
{
        public ApplicationUser()
        {         
            //CoiffeurServiceLevels = new Collection<CoiffeurServiceLevel>();
            //Requests = new Collection<Request>();
            //Tickets = new Collection<Ticket>();        
            //UserRatings = new Collection<Rating>();
            //CouffierRatings = new Collection<Rating>();
        }

        public string PhotoUrl { get; set; }

        public string Lat { get; set; }
        public Language Language { get; set; }

        public string Address { get; set; }
        public string FullName { get; set; }
        public string Lng { get; set; }
        public string PersonalId { get; set; }

        public Place Places { get; set; }
        public long? PlaceId { get; set; }

        public int? CouffierNumber { get; set; } = 1;

        public long CityId { get; set; }
        public City City { get; set; }

        public bool IsSuspended { get; set; }
        public bool IsOnline { get; set; }
        public string ConfirmedToken { get; set; }
        public string ResetPasswordlToken { get; set; }
        public  DateTime BirthDate { get; set; }

        public bool Gender { get; set; } 

        //#region RelationsClass

        public virtual ICollection<CoiffeurServiceLevel> CoiffeurServiceLevels { get; set; }
        // public ICollection<Request> Requests { get; set; }
        ////public ICollection<Request> RequestsCouffier { get; set; }
        //public virtual ICollection<Ticket> Tickets { get; set; }
        public virtual ICollection<Rating> UserRatings { get; set; }
        //public virtual ICollection<Rating> UserRatingsBy { get; set; }
        //public ICollection<IdentityRole> Roles { get; set; }

        //Roles = new Collection<IdentityUserRole>();
        //#endregion
}

当我打电话给我时,我收到了这个错误:

  

消息:调用存储过程时不支持“包含”操作   来源:Microsoft.EntityFrameworkCore.Relational

enter image description here

3 个答案:

答案 0 :(得分:0)

我使用了Ado.net和调用程序

DataTable dt = new DataTable();
            using (SqlConnection sqlConn = new SqlConnection(_context.Database.GetDbConnection().ConnectionString))
            {
                string sql = "<ProcedureName>";
                using (SqlCommand sqlCmd = new SqlCommand(sql, sqlConn))
                {
                    sqlCmd.CommandType = CommandType.StoredProcedure;
                    sqlCmd.Parameters.AddWithValue("@ServiceId", string.Join(',', servicesIds.ToArray()));

                    sqlCmd.Parameters.AddWithValue("@Page", page);
                    sqlCmd.Parameters.AddWithValue("@PageSize", pageSize);
                    sqlConn.Open();
                    using (SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCmd))
                    {
                        sqlAdapter.Fill(dt);
                    }
                }
            }

答案 1 :(得分:0)

我遇到了同样的问题,发现如果分别加载两个实体,只要数据模型支持,它们就会自动链接在一起。

我通过存储过程加载了具有陈列室ID的客户实体,我想从陈列室表中显示陈列室的名称:

首先,我要填充陈列室:

Showroom = await _context.Showroom.ToListAsync();

然后我为客户对象调用存储过程:

Customer = await _context.Customer
            .FromSql("EXEC sp_GetCustomerList @SearchString, @SortString", searchParam, sortParam)
            .ToListAsync();

最后,我现在可以使用以下语法从陈列室列表中访问值:

@Html.DisplayFor(modelItem => item.Showroom.ShowroomName)

我不确定这样做是否会对性能产生很大影响,因为您实际上是在执行两个查询而不是一个。

答案 2 :(得分:0)

您可以通过DbContext.Entry(...)API显式加载导航属性。 https://docs.microsoft.com/en-us/ef/core/querying/related-data#explicit-loading

public IQueryable<ApplicationUser> SelectNearByUser()
{
    var query = "execute dbo.GetCouffierSearch";
    var res = _context.Users.FromSql(query);
    _context.Entry(res)
            .Collection(x => x.CoiffeurServiceLevels)
            .Load();
    return res;
}