【问题标题】:ASP.NET - Entity Framework - Only parameterless constructors and initializers are supported in LINQ to EntitiesASP.NET - 实体框架 - 在 LINQ to Entities 中仅支持无参数构造函数和初始化程序
【发布时间】:2019-01-17 03:52:00
【问题描述】:

我是 asp.net MVC4 和 EntityFramework 的新手。

我在尝试向我的 API 添加新方法时收到此错误:

LINQ to Entities 仅支持无参数构造函数和初始化程序。

这是我的方法:

// GET: api/Partenaires_prestations
        [Authorize]
        [Route("api/Partenaires_prestations")]
        public List<PartenaireMapItem> GetPartenairesWithPrestations()
        {
            Random rnd = new Random();

            var queryString = Request.GetQueryNameValuePairs();

            var prestation = queryString.FirstOrDefault();

            return db.Partenaires
                .Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
                .Select(p => new PartenaireMapItem {
                    IdPartenaire = p.IdPartenaire,
                    FirstName = p.FirstName,
                    LastName = p.LastName,
                    NomComplet = p.LastName.Substring(0,1).ToUpper() + ". " + p.FirstName,
                    Type = p.Type,
                    DureeMin = 50,
                    Lat = p.Lat,
                    Lng = p.Lng,
                    ImageUrl = p.ImageUrl,
                    SeDeplace = p.SeDeplace,
                    ADomicile = p.ADomicile,

                    NoteGlobale = p.NoteClientPartenaires.Sum(x => ((double)(x.NoteAimabilite + x.NotePonctualite +
                                             x.NoteProprete + x.NoteQualite)) / 4) / p.NoteClientPartenaires.Count,
                    Prestations = new List<string>(p.PartenairePrestations.Select(y => y.Prestation.NomPrestation))
                }).ToList();
}

这是我的 PartenaireMapItem 类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Uphair.EfModel;

namespace Uphair.Api.Models.Partenaire
{
    public class PartenaireMapItem
    {
        public int IdPartenaire { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string NomComplet { get; set; }
        public double? Lat { get; set; }
        public double? Lng { get; set; }
        public PartenaireType Type { get; set; }

        public int DureeMin { get; set; }

        public string ImageUrl { get; set; }

        public int SeDeplace { get; set; }

        public bool ADomicile { get; set; }

        public double NoteGlobale { get; set; }

        public ICollection<NoteClientPartenaire> Notes { get; set; }


        public List<String> Prestations { get; set; } 
    }
}

这是堆栈跟踪:

"{"Message":"发生错误。","ExceptionMessage":"LINQ to Entities 中仅支持无参数构造函数和初始化程序。","ExceptionType":"System.NotSupportedException","StackTrace": " 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.NewTranslator.TypedTranslate(ExpressionConverter parent, NewExpression linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) \r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(表达式 linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda (LambdaExpression lambda、DbExpression 输入、DbExpressionBinding& 绑定)\r \n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator。 TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)\r\n 在 System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()\r\n 在 System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan (Nullable1 forMergeOption)\r\n at System.Data.Entity.Core.Objects.ObjectQuery1.c__DisplayClass7.b__6()\r\n 在 System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n at System.Data.Entity.Core.Objects.ObjectQuery1.c__DisplayClass7.b__5()\ r\n 在 System.Data.Entity.Core.Objects.ObjectQuery1.GetResults(Nullable1 forMergeOption)\r\n 在 System.Data.Entity.Core.Objects.ObjectQuery1.&lt;System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator&gt;b__0()\r\n at System.Data.Entity.Internal.LazyEnumerator1.MoveNext()\r\n 在System.Collections.Generic.List1..ctor(IEnumerable1 集合)\r\n 在 System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)\r\n at Uphair.Api.Controllers.PartenairesController.GetPartenairesWithPrestations()\r\n at lambda_method(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.&lt;&gt;c__DisplayClass10.&lt;GetExecutor&gt;b__9(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary2 参数,CancellationToken 取消令牌)\r\n-- - 从先前引发异常的位置结束堆栈跟踪 ---\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.&lt;InvokeActionAsyncCore&gt;d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n 在 System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext()\r\n--- 结束来自先前引发异常的位置的堆栈跟踪 ---\r\n System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r \n 在 System.Web.Http.Filters.AuthorizationFilterAttribute.d__2.MoveNext()\r\n--- 从先前引发异常的位置结束堆栈跟踪 ---\r\n 在 System.Runtime.CompilerServices。 TaskAwaiter.ThrowForNonSuccess(任务任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerN otification(任务任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n 在 System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"}"

任何帮助将不胜感激。

感谢任何愿意花时间阅读/回答我的帖子的人。

【问题讨论】:

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


【解决方案1】:

例外是因为这里

Prestations = new List<string>(p.PartenairePrestations.Select(y => y.Prestation.NomPrestation))

您正在使用List&lt;T&gt; 构造函数和IEnumerable&lt;T&gt; 参数,并且如异常消息所示,LINQ to Entities 仅允许无参数构造函数,即没有参数的构造函数。

只需将其替换为可识别的ToList 扩展方法即可,因此 EF 查询翻译器支持:

Prestations = p.PartenairePrestations.Select(y => y.Prestation.NomPrestation).ToList()

【讨论】:

  • 试过了,但是方法不再返回了。
  • 这应该适用于问题中的原始 L2E 查询,对吧?没有AsEnumerable(),它完全改变了执行上下文。并且应该执行单个 SQL,如果您从 return … 获取 LINQ 查询并将 last ToList() 替换为 ToString(),则应该执行该 SQL
  • 在 Where() 之后添加 AsEnumerable 使异常消失,但现在我需要激活多个结果集,请参阅stackoverflow.com/questions/43264526/…
  • 添加AsEnumerable()?我不想评论其他答案,但在这种特殊情况下它们是完全错误的。我的回答涵盖了您问题中异常的原因以及如何避免它。它不需要AsEnumerable()。整个想法是执行整个服务器端。所以使用问题中的查询,而不是当前接受的答案,只需修改Prestantions = …,如上所示。异常应该消失。问题解决了。如果您有新问题,可能您应该发布一个新问题 :)
  • 您知道吗,实际上您当前与 MARS 的问题是由 AsEnumerable()“修复”引起的,因为正如我所说,“修复”查询选择在不同的上下文中执行(客户端,LINQ到对象),因此由于延迟加载访问的导航属性,它激活了许多额外的 SQL 查询,同时仍在处理主查询,因此是 MARS。如果您可以按照我的建议执行整个服务器端(通过使用 LINQ to Entities 兼容结构),则不会出现不支持或 MARS 相关的异常。
【解决方案2】:

您的异常有重要的细节来解释这里的问题:

LINQ to Entities 仅支持无参数构造函数和初始化器

要像使用对象初始化器语法一样将值放入PartenaireMapItem 对象,您可以在.Where(...) 之后使用.AsEnumerable() 方法。使用 AsEnumerable() 将允许您使用 LINQ to Objects 功能。

return db.Partenaires
            .Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
            .AsEnumerable()
            .Select(p => new PartenaireMapItem {
                IdPartenaire = p.IdPartenaire,
                FirstName = p.FirstName,
                LastName = p.LastName,
                NomComplet = p.LastName.Substring(0,1).ToUpper() + ". " + p.FirstName,
                Type = p.Type,
                DureeMin = 50,
                Lat = p.Lat,
                Lng = p.Lng,
                ImageUrl = p.ImageUrl,
                SeDeplace = p.SeDeplace,
                ADomicile = p.ADomicile,

                NoteGlobale = p.NoteClientPartenaires.Sum(x => ((double)(x.NoteAimabilite + x.NotePonctualite +
                                         x.NoteProprete + x.NoteQualite)) / 4) / p.NoteClientPartenaires.Count,
                Prestations = new List<string>(p.PartenairePrestations.Select(y => y.Prestation.NomPrestation))
            }).ToList();

【讨论】:

  • 似乎工作起来像一个魅力,但我收到另一个错误:“MySql.Data.MySqlClient.MySqlException:已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭。”有什么线索吗?
【解决方案3】:

Entity Framework 为您实例化对象。为了能够做到这一点,它希望您的类中有一个没有参数的构造函数。检查你的类是否有这样的构造函数(我没看到)。

请记住,您的类中可以有多个构造函数。

【讨论】:

  • 如果我理解你的话,我应该在我的 PartenaireMapItem 类中放置一个不带参数的构造函数?
  • 如果这是您与实体框架一起用作数据持有者的类,那么是......
  • 我在 PartenaireMapItem 类中添加了一个无参数 ctor,但没有任何改变,所有其他类都已经有无参数 ctor...我错过了什么?
  • 我要考你的课,给我一些时间
  • 当我只使用 PartenaireMapItem 类来创建数据库表时,它给了我消息:没有定义键,如果你使用流利的 api 在类和数据库之间进行映射,这是正确的.我的假设是您在项目中走得更远,并且您能够存储和检索单个对象。我对么?我正在使用 EF6.0
猜你喜欢
  • 1970-01-01
  • 2014-07-17
  • 2015-07-31
  • 1970-01-01
相关资源
最近更新 更多