【问题标题】:How to use LINQ to query from a list of objects into an existing object?如何使用 LINQ 从对象列表查询到现有对象?
【发布时间】:2010-11-15 16:02:47
【问题描述】:

我不确定这在 LINQ 中是否可行,但我有以下情况:

我通过多个查询多次调用 SharePoint 列表服务。然后,我从所有查询中填充单个对象及其属性。我正在使用 LINQ 来查询返回的 XElement。我知道,如果调用达到这一点,我的 LINQ 查询将只返回一个项目。我目前必须查询一个新对象,然后为每个 Web 服务调用从这个新对象(来自 LINQ)设置我的主对象的属性。 (以下代码示例仅包含需要查询和设置的“Action”项属性的一小部分。)

有什么方法可以将下面的语句“选择”到我现有的“动作”对象中?

var item = (from listItem in result.GetSPListItems()
            select new ContractAction
            {
                Title = listItem.GetSPFieldValue("Title"),
                Description = listItem.GetSPFieldValue("Description"),
                DeliveryOrderID = SPHelper.GetFirstLookupID(listItem.GetSPFieldValue("Delivery Order")),
                EstimatedValue = ((listItem.GetSPFieldValue("Estimated Value") as double?) ?? 0),
                AgreementTypeID = SPHelper.GetFirstLookupID(listItem.GetSPFieldValue("Contract Type")),                                                
            }).FirstOrDefault();

contractAction.Title = item.Title;
contractAction.Description = item.Description;
contractAction.DeliveryOrderID = item.DeliveryOrderID;
contractAction.EstimatedValue = item.EstimatedValue;
contractAction.AgreementTypeID = item.AgreementTypeID;

【问题讨论】:

    标签: c# linq sharepoint


    【解决方案1】:

    你不能简单点:

    action = (from listItem in result.GetSPListItems()
             select new Action
             {
                 Title = listItem.GetSPFieldValue("Title"),
                 Description = listItem.GetSPFieldValue("Description"),
                 DeliveryOrderID = SPHelper.GetFirstLookupID(listItem
                     .GetSPFieldValue("Delivery Order")),
                 EstimatedValue = 
                     ((listItem.GetSPFieldValue("Estimated Value") as double?) ?? 0),
                 AgreementTypeID = SPHelper.GetFirstLookupID(listItem
                     .GetSPFieldValue("Contract Type")),
             }).FirstOrDefault();
    

    【讨论】:

    • 如果Action 有一些其他属性并且 OP 希望其中 5 个属性被查询而不是整个实例修改,我认为这不是一个好主意。
    • @Danny - 如果是这种情况,OP 没有提到任何地方。如果是,他可以简单地将现有值分配给他的 select 语句中的新 Action 实例。
    【解决方案2】:

    首先,您应该重命名类Action,因为Action 是内置库中定义的委托。我将在下面的代码中使用MyAction

    如果你总是需要从SPListItem 获取MyAction,你最好写一个扩展方法把逻辑放在一个地方DRY(不要重复你自己)。

    public static MyAction ToMyAction(this SPListItem item)
    {
        return new MyAction  
           {  
              Title = item.GetSPFieldValue("Title"),  
              Description = item.GetSPFieldValue("Description"),  
              DeliveryOrderID = SPHelper.GetFirstLookupID(item.GetSPFieldValue("Delivery Order")),  
              EstimatedValue = ((item.GetSPFieldValue("Estimated Value") as double?) ?? 0),  
              AgreementTypeID = SPHelper.GetFirstLookupID(item.GetSPFieldValue("Contract Type"))                                                  
           };  
    }
    
    var action = result.GetSPListItems()
                       .Select(item => item.ToMyAction())
                       .FirstOrDefault();
    //var action = (from item in result.GetSPListItems()
    //              select item.ToMyAction()).FirstOrDefault();
    

    【讨论】:

      【解决方案3】:

      首先,因为我知道我只会得到一个结果,所以我只需要放弃使用 linq 查询的“选择”部分的想法。一旦我这样做了,答案就很明显了。

      //just grab the first item
      var item = result.GetSPListItems().FirstOrDefault();
      
      //then grab the properties into the existing ContractActionEntity                             
      contractAction.Title = item.GetSPFieldValue("Title");
      contractAction.Description = item.GetSPFieldValue("Description");
      contractAction.DeliveryOrderID = SPHelper.GetFirstLookupID(item.GetSPFieldValue("Delivery Order"));
      contractAction.EstimatedValue = item.GetSPFieldValue("Estimated Value").ToNullableDouble();
      contractAction.AgreementTypeID = SPHelper.GetFirstLookupID(item.GetSPFieldValue("Contract Type")),
      

      感谢大家让我更多地思考这个问题并引导我朝着答案的方向前进。

      【讨论】:

        【解决方案4】:

        您可以在一个大查询中编写查询。因此,例如,您可以:

        var item = (from listItem in result.GetSPListItems()
                from query2Outer in result.SecondQuery().Where(x => x.ItemEdp == it.ItemEdp).DefaultIfEmpty() // This is an outer join
                select new Action
                {
                    //if the one query didn't return an item then it sets the properties to the default values
                    Example = (query2Outer == null ? "Default Value" : query2Outer.Example),
                    Title = listItem.GetSPFieldValue("Title"),
                    Description = listItem.GetSPFieldValue("Description"),
                    DeliveryOrderID = SPHelper.GetFirstLookupID(listItem.GetSPFieldValue("Delivery Order")),
                    EstimatedValue = ((listItem.GetSPFieldValue("Estimated Value") as double?) ?? 0),
                    AgreementTypeID = SPHelper.GetFirstLookupID(listItem.GetSPFieldValue("Contract Type")),                                                
                }).FirstOrDefault();
        

        【讨论】:

          【解决方案5】:

          扩展方法方法的替代方法是:

          public static void SelectFirstInto(this IEnumerable<ContractAction> items, ContractAction target)
          {
              var source = items.FirstOrDefault();
          
              if(source != null)
              {
                  target.Title = source.Title,  
                  target.Description = source.Description ,  
                  target.DeliveryOrderID = source.DeliveryOrderID,  
                  target.EstimatedValue = source.EstimatedValue, 
                  target.AgreementTypeID = source.AgreementTypeID                                                 
               }
          }
          

          那么你可以这样做:

          ContractAction targetAction = new ContractAction();
          var item = (from listItem in result.GetSPListItems()
                      select new ContractAction
                      {
                          Title = listItem.GetSPFieldValue("Title"),
                          Description = listItem.GetSPFieldValue("Description"),
                          DeliveryOrderID = SPHelper.GetFirstLookupID(listItem.GetSPFieldValue("Delivery Order")),
                          EstimatedValue = ((listItem.GetSPFieldValue("Estimated Value") as double?) ?? 0),
                          AgreementTypeID = SPHelper.GetFirstLookupID(listItem.GetSPFieldValue("Contract Type")),                                                
                      }).SelectFirstInto(targetAction);
          

          请记住,如果列表为空,则目标对象保持不变。这可能是您需要相应处理的事情。

          【讨论】:

          • 这与我想要的非常接近,但我想消除抓取属性然后在现有对象中再次设置它们的冗余。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-07
          • 2019-01-28
          • 2014-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多