【问题标题】:"Processing of the LINQ expression 'GroupByShaperExpression" Got error after upgrade to ef core . 5“处理 LINQ 表达式 'GroupByShaperExpression” 升级到 ef core 后出错。 5
【发布时间】:2021-03-31 20:58:08
【问题描述】:

我的项目是 .net core 2.2 并升级到 .net 5 和 EF 5.0 我的最后一个查询是

 public IList<Group<String, UsefullLink>> GetAllGroupActive()
 {
     return (from b in _db.UsefullLinks
             group b by b.UseFullLinkType.Name into g
             select new Univer.Business.Model.Group<string, UsefullLink> 
             { 
                 Key = g.Key, 
                 Values = g 
             }).ToList();        
 }

我的模特

public class UsefullLink
{
    public int Id { get; set; }

    public string Name { get; set; }


    public bool Active { get; set; }

    public DateTime CreateDate { get; set; }

    public string Image { get; set; }

    public int LinkTypeId { get; set; }

    public LinkType LinkType { get; set; }
  
    public int Priority { get; set; }
    
...       
 
    public string Description { get; set; }
  

    public int UseFullLinkTypeId { get; set; }
   
    public UseFullLinkType UseFullLinkType { get; set; }
}

public class UseFullLinkType
{
    public int Id { get; set; }
    [Required, DataType(DataType.Text)]
    public string Name { get; set; }
  
    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

    [Required, DataType(DataType.Date)]
    public DateTime InputDate { get; set; }

    public int Priority { get; set; }

   public ICollection<UsefullLink> UsefullLinks { get; set; }
}

我的看法

@using Univer.Business.Model
@model List<Group<string, Univer.Model.UsefullLink>>
@{
   ViewData["Title"] = "ServiceTebbedTable";
}
<div class="container">
<div class="row UsefullLink ">

    <div class="card ">
        <div class="card-header"> <a asp-action="ServiseTable" asp-controller="Home" asp-area="">service table</a></div>
        <ul class="row" style="margin-left:25px ;margin-right:25px;">

            @foreach (var group in Model)
            {
                <li class="row col-md-12" id="cut-diamond"> @group.Key</li>
                <li class="m-1"></li>
                foreach (var link in group.Values)
                {
                    <li class="col-md-4 mt-2  justify-content-center">
                        @if (link.Image != "1")
                        {
                            <img src="@Url.Content(link.Image)" class="UsefullLink-icon" />
                        }
                        else
                        {
                            <img src="~/images/Logo200blue.png" class="UsefullLink-icon" />
                        }
                        <a href="@link.LinkUrl" class="justify-content-center" target="_blank"> @link.Name</a>

                    </li>
                }
            }
        </ul>
    </div>
   </div>
</div>

运行项目后出现此错误

InvalidOperationException:处理 LINQ 表达式“GroupByShaperExpression: KeySelector: u.Name, 元素选择器:实体形状表达式: 实体类型:UsefullLink 值缓冲区表达式: ProjectionBindingExpression:EmptyProjectionMember IsNullable: 假

更新1: 对于组,我在 Univer.Business.Model 中有这个

public class Group<k, T>
{
        public k Key;
        public IEnumerable<T> Values;
}

更新2 这是我的存储库的构造函数 公共类 UsefullLinkRepository : IUsefullLinkRepository { 私有只读UniverContext _db;

    public UsefullLinkRepository(UniverContext db)
    {
        _db = db;
    }
}

我将它的方法更改为

var data = from b in _db.UsefullLinks.AsEnumerable()
                   join c in _db.UseFullLinkTypes on b.UseFullLinkTypeId equals c.Id
                   group b by b.UseFullLinkType.Name into g
                   select g;

        return data.Select(g => new Group<string, UsefullLink>
        {
            Key = g.Key,
            Values = g
        }).ToList();

运行后Update2 我收到了这个错误

InvalidOperationException: 已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭。

【问题讨论】:

  • 我建议将 Where 移近 ToListAsync。它大大简化了查询翻译。
  • 你能分享一下你的模型的详细代码吗?你的 UsefullLink 和 UseFullLinkType 是什么?

标签: c# entity-framework linq asp.net-core


【解决方案1】:

这里的问题是 EF 2.x 在客户端静默评估不可翻译的查询。在这种情况下,EF Core 5 没有抛出正确的异常是一个错误。

考虑重写您的查询

var grouped = from b in _db.UsefullLinks.AsEnumerable()
              group b by b.UseFullLinkType.Name into g
              select g;

return grouped.Select(g => new Univer.Business.Model.Group<string, UsefullLink> 
    { 
        Key = g.Key, 
        Values = g // this assignment is not translatable
    }).ToList(); 

【讨论】:

  • 之后我收到此错误“无法翻译给定的“GroupBy”模式。在“GroupBy”之前调用“AsEnumerable”以在客户端对其进行评估。'
  • 抱歉,已更正查询。来晚了,我的错。
【解决方案2】:
 return (from b in _db.UsefullLinks
            group b by b.UseFullLinkType.Name into g
            select new Univer.Business.Model.Group<string, UsefullLink> 
            { Key = g.Key, Values = g }).ToList(); 

在这里,UsefullLinks 集合是否将“Key”作为列?您可能想使用 g.Name 而不是 g.Key

【讨论】:

  • 我有一堂有“钥匙”的课,我也更新了我的问题
  • Group 类有“键”。但是上面的“g”集合是 UsefullLinks 类型的,它没有“Key”属性。因此问题是“g.Key”是否需要替换为“g.Name”??
【解决方案3】:

如下改变:

var data = from b in _db.UsefullLinks.AsEnumerable()
                join c in _db.UseFullLinkType.AsEnumerable() on b.UseFullLinkTypeId equals c.Id
                group b by b.UseFullLinkType.Name into g
                select g;

return data.Select(g => new Group<string, UsefullLink>
{
    Key = g.Key,
    Values = g 
}).ToList();

结果:

【讨论】:

  • 感谢您的宝贵时间,我知道在 Enumerable 中我们不会向数据库发送查询,也没有打开的连接,因为在这种情况下我会收到此错误:'这里已经是打开与此 Connection 关联的 DataReader,必须先关闭它。'
  • 它在我的 .net 5 项目中可以很好地工作。您能否分享一下您的_db 关于您是如何定义 dbcontext 的?
  • 它在更新之前运行良好,并且有很多方法可以从数据库中获取数据,我也更新了我的问题
  • 嗨@sunny,尝试制作MultipleActiveResultSets=true
  • 好的,我在很多答案中都看到了,但这是正确的方法吗?在此之前打开哪个连接?使用这种方法是否有可能失去对连接的控制?
【解决方案4】:

感谢您的帮助,在您的帮助下,我得到了很多想法,对此我有很多未知的想法,另一方面我喜欢 Linq Lambda,我的建议之一,我得到了添加 "MultipleActiveResultSets=true" 但我认为在升级我的项目之前我没有问题,这意味着这个问题来自我的查询,并且下次如果我想编辑我的另一个查询,也许我向数据库发送了很多连接,这对性能不利, 另一个想法是我使用项目业务层的外部类,它来自.net core 2.2,在.net core 5.0中我尝试使用更好的方法, 结果是,我从我的连接字符串中删除了 "MultipleActiveResultSets=true" 并从另一层项目中减少了对组类的使用,最终的查询变成了我的存储库:

  return _db.UsefullLinks
            .Join(_db.UseFullLinkTypes.AsEnumerable(),
                  ul => ul.UseFullLinkTypeId,
                  ult => ult.Id,
                  (ul, ult) => new { ul = ul, ult = ult }).AsEnumerable()
            .GroupBy(
            x=>x.ul.UseFullLinkType.Name,x=>x.ul )
            .Select (g=>g).ToList();

在我看来,我的变化很小

@model List<IGrouping<string, Univer.Model.UsefullLink>>
@{
 ViewData["Title"] = "ServiceTebbedTable";
}

<div class="container">
<div class="row UsefullLink ">

    <div class="card ">
        <div class="card-header"> <a asp-action="ServiseTable" asp-controller="Home" asp-area="">Service Table</a></div>
        <ul class="row" style="margin-left:25px ;margin-right:25px;">

            @foreach (var group in Model)
            {
                <li class="row col-md-12" id="cut-diamond"> @group.Key</li>
                <li class="m-1"></li>
                foreach (var link in group)
                {

                    <li class="col-md-4 mt-2  justify-content-center">

                        @if (link.Image != "1")
                        {
                            <img src="@Url.Content(link.Image)" class="UsefullLink-icon" />
                        }
                        else
                        {
                            <img src="~/images/Logo200blue.png" class="UsefullLink-icon" />
                        }
                        <a href="@link.LinkUrl" class="justify-content-center" target="_blank"> @link.Name</a>

                    </li>

                   
                }
            }
        </ul>
    </div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-13
    • 2021-05-14
    • 2021-05-08
    • 1970-01-01
    • 2021-09-15
    • 2012-08-21
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多