2012-10-25 103 views
1

我第一次使用EF4/LINQ并遇到问题。在foreach循环中更新对象

private static void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     CallOutcomeSubmission los = new CallOutcomeSubmission();  
     client = connectToService(); 

     try 
     { 
     using (var context = new CallOutcomeContext()) 
     { 
      // List of available actions 
      private static string ACTION_CALL_ATTEMPT = "Call Attempt"; 
      DateTime oneDayAgo = DateTime.Now.AddHours(-24); 
      var query = from co in context.T_MMCallOutcome 
         join ca in context.T_Call on co.CallID equals ca.CallID 
         join lv in context.T_LeadVendorEmailHeader on co.LeadVendorEmailID equals lv.LeadVendorEmailID 
         where co.EnteredOn > oneDayAgo && co.MMLeadActionID == null 
         select new 
         { 
          co.CallOutcomeID, 
          co.CallID, 
          co.LeadVendorEmailID, 
          MMLeadID = lv.email_text, 
          ca.OutcomeID, 
          lv.FranchiseNumber, 
          co.MMLeadActionID, 
          co.LeadAction 
         }; 

      // if any results found for query 
      if (query.Any()) 
      { 
       foreach (var call in query.ToList()) 
       { 
        // if the franchise exists 
        if (client.FranchiseExists(int.Parse(call.FranchiseNumber))) 
        { 
        switch (call.OutcomeID) 
        { 
         case 39: // Not Answered 
          call.LeadAction = ACTION_CALL_ATTEMPT; 
          break; 
         case 43: // Remove from Call List 
          break; 
         default: // If the OutcomeID is not identified in the case statement 
          break; 
        } // switch 

        } 
        else 
        { 
        los.eventLog.WriteEntry("CallOutcomeSubmission.OnTimedEvent: No franchise found with franchise ID " + call.FranchiseNumber); 
        } 

        // Save any changes currently on context 
        context.SaveChanges(); 

       } // foreach 

      } 

      // if no results found from query write system log stating such 
      else 
      { 
       los.eventLog.WriteEntry("CallOutcomeSubmission.OnTimedEvent: No new entries found"); 
      } 
     } // using 

     client.Close(); 
     } 
     catch (System.TimeoutException exception) 
     { 
     los.eventLog.WriteEntry("CallOutcomeSubmission.OnTimedEvent:" + exception.ToString()); 
        client.Abort(); 
     } 
     catch (System.ServiceModel.CommunicationException exception) 
     { 
     los.eventLog.WriteEntry("CallOutcomeSubmission.OnTimedEvent:" + exception.ToString()); 
        client.Abort(); 
     } 
    } 

当我尝试做任务:

call.LeadAction = ACTION_CALL_ATTEMPT; 

我得到的

Property or indexer 'AnonymousType#2.LeadAction' cannot be assigned to -- it is read only 
生成错误我使用foreach循环如下循环直通LINQ查询的结果

我似乎无法找到任何有关执行Google搜索的特定错误,但我不确定自己做错了什么。是否因为原始查询包含连接?

如何在foreach循环中完成call.LeadAction的赋值?

我也想知道是否有设计问题的方式我写了查询或执行任何操作,因为这是我第一次进入EF/LINQ。

回答

0

您正在创建一个新的匿名类型 - 与Linq连接,然后尝试设置该值。你真正想要做的是更新电话的LeadAction是否正确?

EF如何知道将您的新查询翻译回实体,以便它可以返回到数据库?这将不得不经历很多环节,而且这是不可能的。

你可以做什么,是检索数据库中的Call并设置LeadAction这样 - 我用查找,假设CallID是你PK:

    case 39: // Not Answered 
         var thisCall = context.T_Call.Find(call.CallID) 
         thisCall.LeadAction = ACTION_CALL_ATTEMPT;        
         break; 
+0

良好,即工作。需要说明的是,EF无法将作业转换回实体的原因在于查询中的连接?如果原始查询(我的代码示例中的'查询')没有包含任何连接,那么foreach循环中的赋值就可以工作? – BrianKE

+0

正确 - 如果你要返回实际的实体类型(在这种情况下调用)。 –

+0

这不是真正的导致问题的连接,而是你正在返回一个新对象的事实。如果你返回了一个新的对象,例如new {co.CallID,co.LeadAction},那么你会在没有连接的情况下得到相同的问题。您可能还可以通过返回内部新的选择新 {合作, MMLeadID = lv.email_text, ca.OutcomeID, ... }完整实体,以避免问题; – sgmoore