获取字典LINQ中的第一个匹配项

时间:2013-08-15 17:07:38

标签: c# linq

我有以下代码,即使在代码中第一次出现后它仍然保持循环。我想停止但我无法在我的案例中应用Any

    public List<FieldConfiguration> GetListOfProvisionsForBenefits(Dictionary<int, string> benefits)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("SELECT ProvisionID ,BenefitID,ProvisionName, BPROV_Flags FROM BenefitProvisions WHERE");
        int intSQLvar = 0;
        string strSeperator = string.Empty;
        foreach (KeyValuePair<int, string> benefit in benefits)
        {

            sb.AppendFormat(" {0} BenefitID=@benerfit{1}", strSeperator, intSQLvar);
            intSQLvar++;
            strSeperator = "OR";
        }

        SqlConnection con = new SqlConnection(m_strDBConnectionString);
        SqlDataAdapter sqlDataAdapter = new SqlDataAdapter();
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = con;
        cmd.CommandText = sb.ToString();
        intSQLvar = 0;
        foreach (KeyValuePair<int, string> benefit in benefits)
        {
            cmd.Parameters.Add(string.Format("@benerfit{0}", intSQLvar), SqlDbType.Int, 32).Value = benefit.Key.ToString();
            intSQLvar++;
        }

        DataSet ds = new DataSet();
        try
        {
            con.Open();
            sqlDataAdapter.SelectCommand = cmd;
            sqlDataAdapter.Fill(ds);
        }
        finally
        {
            if (con != null)
            {
                con.Close();
                con = null;
            }
        }
        List<ProvisionDetails> lstProvisions = new List<ProvisionDetails>();

        if (ds != null && ds.Tables[0].Rows.Count > 0)
        {
                lstProvisions = (from r in ds.Tables[0].AsEnumerable()
                                select new ProvisionDetails()
                        {
                            ID = r.Field<int>("ProvisionID"),
                            Name = r.Field<string>("ProvisionName"),
                            BenefitID = r.Field<int>("ProvisionID"),
                            OptionValue =  r.Field<int>("ProvisionID") 
                        }).ToList();

            if (benefits.Count == 1)
            {
                return (from p in lstProvisions
                        select new FieldConfiguration()
                        {
                            Name = p.Name,
                            ProvisionFieldID = p.ID.ToString(),
                            FieldType = Configuration.SyncapayPlus.FieldType.Provision,
                            Caption = (from b in benefits 
                                           where(b.Key == p.BenefitID)
                                       select string.Format("{0}_{1}", b.Value, p.Name)).ToString() // to do change caption  benefitname_provisionName
                        }).ToList();
            }
            else
            {
                return (from p in lstProvisions.GroupBy(x => x.Name)
                .Where(y => y.Count() > 1)
               .SelectMany(z => z)
                        select new FieldConfiguration()
                        {
                            Name = p.Name,
                            ProvisionFieldID = p.ID.ToString(),
                            FieldType = Configuration.SyncapayPlus.FieldType.Provision,
                            SourceOption = p.OptionValue.ToString(),
                            Caption =
                            (from b in benefits
                             where (b.Key == p.BenefitID)
                             select string.Format("{0}_{1}", b.Value, p.Name)).ToString() // to do change caption  benefitname_provisionName
                        }).ToList();
            }


        }
        return null;

    }

我想在本节中应用ANY,我会得到标题;当我找到第一个好处时,我希望它退出并分配它:

Caption =
     (from b in benefits
     where (b.Key == p.BenefitID)
     select string.Format("{0}_{1}", b.Value, p.Name)).ToString() // to do change caption  benefitname_provisionName
                           }).ToList();
            } 

4 个答案:

答案 0 :(得分:5)

如果您知道总会有至少一个这样的好处 - 或者您不介意使用占位符来获取缺失值 - 您可以使用以下内容:

Caption = string.Format("{0}_{1}",
                        benefits.Where(b => b.Key == p.BenefitID)
                                .Select(b => b.Value)
                                .FirstOrDefault(), // Or First
                        p.Name);

我建议你不要混淆和匹配你的查询表达式和点符号这么多 - 目前它很混乱。

答案 1 :(得分:2)

您可以在此处使用FirstorDefault。 (在我的评论后将其发布为答案)

Caption = string.Format("{0}_{1}",
                        benefits.Where(b => b.Key == p.BenefitID)
                                .Select(b => b.Value)
                                .FirstOrDefault(), // Or First
                        p.Name);

它将返回序列的第一个元素,如果序列不包含元素,则返回默认值

答案 2 :(得分:0)

我同意你在这里做得太多的评论,这使得可读性变得非常困难,因此将使调试和未来的可维护性变得非常困难。

但是,要回答您的问题,您可能需要尝试以下内容:

(from b in benefits
 where (b.Key == p.BenefitID)
 select string.Format("{0}_{1}", b.Value, p.Name)).First()

 (from b in benefits
  where (b.Key == p.BenefitID)
  select string.Format("{0}_{1}", b.Value, p.Name)).FirstOrDefault()

我相信.ToString()会是多余的。

答案 3 :(得分:0)

首先,修复缩进,并且在不需要时不要在查询语法和传统语法之间切换。这样可以更容易发现和理解问题。

return (from p in lstProvisions
        group x by x.Name into y
        where y.Count() > 1
        from z in y
        select new FieldConfiguration()
          {
            Name = p.Name,
            ProvisionFieldID = p.ID.ToString(),
            FieldType = Configuration.SyncapayPlus.FieldType.Provision,
            SourceOption = p.OptionValue.ToString(),
            Caption = (from b in benefits
                       where b.Key == p.BenefitID
                       select string.Format("{0}_{1}", b.Value, p.Name)
                      ).ToString()
          }
       ).ToList()

在询问有关代码的问题时,您可能还想考虑不使用x,y,z等变量名。

所以,现在,我可以看到你的问题所在:你在查询中使用ToString,但你可能想要第一个Caption:

return (from p in lstProvisions
        group x by x.Name into y
        where y.Count() > 1
        from z in y
        select new FieldConfiguration()
          {
            Name = p.Name,
            ProvisionFieldID = p.ID.ToString(),
            FieldType = Configuration.SyncapayPlus.FieldType.Provision,
            SourceOption = p.OptionValue.ToString(),
            Caption = (from b in benefits
                       where b.Key == p.BenefitID
                       select string.Format("{0}_{1}", b.Value, p.Name)
                      ).First() // perhaps FirstOrDefault() or FirstOrDefault() ?? ""
          }
       ).ToList()

或者,如果您想要所有权益的字符串表示,您可以再次使用string.Join而不是First。