如何使用 linq 和 c# 从查询中创建包含另一个对象类型的列表的列表对象

本文关键字:列表 包含另 一个对象 类型 创建 对象 linq 何使用 查询 | 更新日期: 2023-09-27 18:37:07

我正在尝试使用 linq 返回一个包含另一个对象列表的对象列表作为 databmember。 我已经尝试了显示的示例,但每次尝试都会收到不同的错误。其中之一如下:LINQ to Entities 无法识别方法 'System.Collections.Generic.List 1[SunGard.Tools.Notifications.LinkVariable] ToList[LinkVariable](System.Collections.Generic.IEnumerable 1[SunGard.Tools.Notifications.LinkVariable])' 方法,并且此方法无法转换为存储表达式。

我有一个对象(AlertMessageReturn),其中包含一些字符串数据成员以及另一个对象(List)的列表。 我有一个定义 LinkVarible 的类和一个包含值的表。我的查询如下所示:

AlertMessagesQuery = from alertMessage in this.context.AlertMessages
where alertMessage.UserId=UserId                                              
select new AlertMessageReturn()
{ PAM_ShortMessage = alertMessage.PAM_ShortMessage,
PAM_LongMessage = alertMessage.PAM_LongMessage,
PAM_LongMessageRemote = alertMessage.PAM_LongMessageRemote,
LinkVariables = (from linkVariable in this.context.AlertMessageLinks
from user in this.context.AlertMessageUsers
 where user.PAMU_PAM_ID == linkVariable.PAML_PAM_ID && user.PAMU_UserId == UserId
 select new LinkVariable()
  {
  Name = linkVariable.PAML_SessionVariableName,
  Value = linkVariable.PAML_SessionVariableValue
   })
};

该错误与为链接变量返回的类型有关。请帮忙。

我更改了代码,如下所示:

LinkDataQuery = from linkData in this.context.AlertMessageLinks
   from user1 in this.context.AlertMessageUsers
    where user1.PAMU_PAM_ID == linkData.PAML_PAM_ID && user1.PAMU_UserId == UserId
     select new LinkData
       {
        Name = linkData.PAML_SessionVariableName,
          Value = linkData.PAML_SessionVariableValue
         };
var links = LinkDataQuery.ToList();
    AlertMessagesQuery = from alertMessage in this.context.AlertMessages
where alertMessage.UserId=UserId                                              
select new AlertMessageReturn()
 { PAM_ShortMessage = alertMessage.PAM_ShortMessage,
   PAM_LongMessage = alertMessage.PAM_LongMessage,
   PAM_LongMessageRemote = alertMessage.PAM_LongMessageRemote,
    LinkVariables = links
 };

var AlertMessages = AlertMessagesQuery.ToList();  // this is where the error point to
                        if (AlertMessages.Any())
                        {
                            return AlertMessages;
                        }

我现在得到的错误是:System.NotSupportedException:无法创建类型为"SunGard.Tools.Notifications.LinkData"的常量值。在此上下文中仅支持基元类型("Int32、字符串和 Guid")。

如何使用 linq 和 c# 从查询中创建包含另一个对象类型的列表的列表对象

LINQ to SQL 引擎无法将生成LinkVariables的子查询转换为 SQL。 更重要的是,SQL不能返回这样的嵌套数据集。

每当收到"无法转换为存储表达式"类型的消息时,这都表明您正在使用 linq 执行某些操作,该操作正在尝试转换为其他语句(通常是 SQL)。 例如,如果你说

....select new MyObject
    {
         Id = Guid.Parse( passedIdentity ),
         ....
    }

虽然这是一个完全有效的 C# 语句,但您将收到一个错误,即 linq 无法处理 Guid.Parse。 如果可以将变量移动到查询中使用的外部变量中,那么它将起作用。 所以你会做...

string name = linkVariable.PAML_SessionVariableName;
string nValue = ....
....
select New LinkVariable
{
    Name=name,
    Value=nValue
};

也。。。您不需要"选择新"语句上的结束括号。

虽然 LINQ to SQL 可以带回对象层次结构,但它不能投影到不属于模型的类型中。不要投影到 AlertMessageReturn 类型中,而是尝试投影到代码的 IQueryable 部分中的匿名类型。完成数据库查询的结构后,强制返回结果(使用 AsEnumerable),然后将其投影到 AlertMessageReturn 类型中。它的开销更大,但确实有效。或者,您可以使用自动映射器之类的内容将匿名类型转换为结果类型。

    AlertMessagesQuery = 
      from alertMessage in this.context.AlertMessages 
      where alertMessage.UserId=UserId                                               
      select new 
      {
         alertMessage.PAM_ShortMessage, 
         alertMessage.PAM_LongMessage, 
         alertMessage.PAM_LongMessageRemote, 
         LinkVariables = from linkVariable in this.context.AlertMessageLinks 
                         from user in this.context.AlertMessageUsers 
                         where user.PAMU_PAM_ID == linkVariable.PAML_PAM_ID && user.PAMU_UserId == UserId 
                         select new  
                         { 
                             Name = linkVariable.PAML_SessionVariableName, 
                             Value = linkVariable.PAML_SessionVariableValue 
                         }) 
      }; 
    var alertMessageResults = 
      from message in AlertMessagesQuery.AsEnumerable()
      select new AlertMessageResult 
      {
        PAM_ShortMessage = mesage.PAM_ShortMessage,
        PAM_LongMessage = message.PAM_LongMessage,
        PAM_LongMessageRemote = message.PAM_LongMessageRemote,
        LinkVariables = (from variable in message.LinkVariables
                        select new LinkVariable { Name=variable.Name, Value = variable.Value})
                        .ToList()
      };
   return alertMessageResults.ToList();