【问题标题】:Getting error that "'object' does not contain a definition for 'key'" while accessing the key property in Asp.Net在访问 Asp.Net 中的 key 属性时出现“'object'不包含'key'的定义”的错误
【发布时间】:2021-03-31 03:56:21
【问题描述】:

我进行了很多研究,但我无法理解为什么会出现此错误,在调试时我可以看到“fgroup”中键的值,但它仍然抛出以下错误:-

{
    "Message": "An error has occurred.",

    "ExceptionMessage": "'object' does not contain a definition for 'key'",

    "ExceptionType": "Microsoft.CSharp.RuntimeBinder.RuntimeBinderException",

    "StackTrace": "   at CallSite.Target(Closure , CallSite , Object )\r\n   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)\r\n   at WEBAPINILAYAM.Controllers.HomeController.TempMethod(List`1 firstRecord, List`1 secoudRecord)\r\n   at WEBAPINILAYAM.Controllers.HomeController.<GetUserList>d__1.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.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.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.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.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.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.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.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.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.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"

}

请在下面找到我的代码:-

 var flatuser = await (from f in DatabaseContext.FlatUserDetails
                                  where f.SocietyCode.Equals(SocietyCode)                                   
                                  select new
                                  { 
                                      userName = f.Users.UserName,
                                      fullName = f.Users.FullName,
                                      phoneNumber = f.Users.PhoneNumber,
                                      email = f.Users.Email,                       
                                      flatNumber = f.FlatDetails.FlatNumber,
                                      buildingNumber = f.BuildingDetails.BuildingNumber

                                  }).GroupBy(x => x.userName).ToListAsync<dynamic>();

  foreach (var fgroup in flatuser)
    {
                                
                String k = fgroup.key;  // Getting error at this line

  foreach(var temp in fgroup)
           {
                 // accessing the object

            }

     }

请帮助我,我想获取密钥的值。

【问题讨论】:

  • 我也试过“fgroup.Key”,但还是同样的错误。
  • 您是否在视图中使用foreach
  • 不,这是一个 Web API,我在控制器的方法中使用它。
  • 你为什么用dynamic
  • 我使用的是动态的,因为我没有使用模型类对象,select里面的所有变量都是匿名类型的。如果我删除动态,那么我必须首先创建一个模型类并使用定义的属性在查询中创建它的对象。

标签: asp.net linq group-by


【解决方案1】:

您的错误原因是使用了您的.ToListAsync&lt;dynamic&gt;();

解决方案是使用.ToListAsync();结束您的查询

... select 中的所有变量都是匿名类型的。如果我删除动态,那么我必须首先创建一个模型类并在查询中使用定义的属性创建它的对象

只有当你想从一个方法中返回获取的数据时才这样。如果您只想将它​​们放在匿名类型中,并在它之后立即使用,就像您在代码中所做的那样,那么您可以使用您的匿名类型。

让我们用一个简单的例子来做这件事。让我们创建一个客户、一个客户序列和一个 GroupbBy。

只需在一个简单的控制台程序中执行此操作:

class Program
{
    static void Main(string[] args)
    {
        var flatUsers = new []
        {
            new {Id=1, UserName="A", FullName="A B"},
            new {Id=2, UserName="B", FullName="B C"},
            new {Id=3, UserName="C", FullName="D E"},
            new {Id=4, UserName="A", FullName="A E"},
            new {Id=5, UserName="C", FullName="C D"},
            new {Id=6, UserName="D", FullName="D E"},
            new {Id=7, UserName="A", FullName="A D"},
            new {Id=8, UserName="B", FullName="D F"},
       };

在 Visual Studio 中,如果您将鼠标悬停在变量 flatUsers 上,它会说这是一个匿名类型的数组。

对此进行实验。添加ToList() 看看会发生什么,或者添加Select(flatUser =&gt; new {...} 看看结果如何。

将具有相同UserName 的 flatUser 分组:

var flatUsersGroupedByUserName = flatUsers.GroupBy(flatUser => flatUser.UserName);

再次:悬停鼠标。是说该变量是一个`IEnumerable>

现在我们可以使用这种匿名类型了吗?让我们试试吧:

foreach (var flatUserGroup in flatUsersGroupedByUserName)
{
    Console.WriteLine("Flat users in group " + flatUserGroup.Key.ToString()
    foreach (flatUser in flatUserGroup)
    {
         Console.WriteLine("[{0}] {1} - {2} ", flatUser.Id, flatUser.UserName, flatUser.FullName);
    }
}

所以,如果你正在创建一个匿名类型,你可以使用它,只要你在同一个方法中。

您不能返回方法的匿名类型:它需要返回类型。

<return type needed here> GetFlatUserGroups (...);

当然,您可以在这里使用List&lt;dynamic&gt; 作为返回类型,但在这种情况下,您的方法的用户很难知道列表中的内容。我不确定这是否明智。直到运行时才会检测到错误。如果您真的无法告诉方法的调用者返回值中的内容,请考虑返回 List 并让您的调用者使用反射来找出其中的内容。但同样:尽量避免这种情况。您不想为返回值键入类这一事实不是一个好的理由。问问你的项目负责人,他会同意的。

总结:请务必使用匿名类型。做一些实验来熟悉它们。匿名类型具有完整的类型检查。您将在编译时检测到错误。尽量避免使用动态。

【讨论】:

    猜你喜欢
    • 2020-09-19
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2020-01-09
    • 2016-06-06
    相关资源
    最近更新 更多