web-dev-qa-db-ja.com

シーケンスに複数の要素が含まれています

Linqを介して「RhsTruck」タイプのリストを取得し、それらを表示する際に問題が発生しています。

RhsTruckには、Make、Model、Serialなどのプロパティがあります... RhsCustomerには、CustomerName、CustomerAddressなどのプロパティがあります。

「シーケンスに複数の要素が含まれています」というエラーが表示され続けます。何か案は?私はこれに間違った方法でアプローチしていますか?

public RhsCustomer GetCustomer(string customerNumber)
{
    using (RhsEbsDataContext context = new RhsEbsDataContext() )
    {
        RhsCustomer rc = (from x in context.custmasts
                          where x.kcustnum == customerNumber
                          select new RhsCustomer()
                        {
                            CustomerName = x.custname,
                            CustomerAddress = x.custadd + ", " + x.custcity
                            CustomerPhone = x.custphone,
                            CustomerFax = x.custfax
                        }).SingleOrDefault();
        return rc;
    }
}

public List<RhsTruck> GetEquipmentOwned(RhsCustomer cust)
{
    using (RhsEbsDataContext context = new RhsEbsDataContext())
    {
        var trucks = (from m in context.mkpops
                      join c in context.custmasts
                        on m.kcustnum equals c.kcustnum
                      where m.kcustnum == cust.CustomerNumber
                      select new RhsTruck
                    {
                        Make = m.kmfg,
                        Model = m.kmodel,
                        Serial = m.kserialnum,
                        EquipID = m.kserialno1,
                        IsRental = false
                    }).ToList();
        return trucks;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    string testCustNum = Page.Request.QueryString["custnum"].ToString();

    RhsCustomerRepository rcrep = new RhsCustomerRepository();
    RhsCustomer rc = rcrep.GetCustomer(testCustNum);
    List<RhsTruck> trucks = rcrep.GetEquipmentOwned(rc);

    // I want to display the List into a Gridview w/auto-generated columns
    GridViewTrucks.DataSource = trucks;
    GridViewTrucks.DataBind();   
}
103
Calvin

問題は、 SingleOrDefault を使用していることです。このメソッドは、コレクションに正確に0または1つの要素が含まれる場合にのみ成功します。 FirstOrDefault を探していると思います。これは、コレクション内の要素の数に関係なく成功します。

240
JaredPar

SingleOrDefault メソッドは、シーケンスに複数の要素がある場合にExceptionをスローします。

どうやら、GetCustomerのクエリは複数の一致を見つけています。そのため、クエリを絞り込むか、ほとんどの場合、特定の顧客番号に対して複数の結果が得られる理由をデータで確認する必要があります。

23
Mehmet Aras
Use FirstOrDefault insted of SingleOrDefault..

SingleOrDefaultは、SINGLE要素を返します。要素が見つからない場合はnullを返します。 Enumerableで2つの要素が見つかった場合、表示されている例外をスローします

FirstOrDefaultは、見つかった最初の要素を返します。要素が見つからない場合はnullを返します。述語に一致する要素が2つある場合、2番目の要素は無視されます

   public int GetPackage(int id,int emp)
           {
             int getpackages=Convert.ToInt32(EmployerSubscriptionPackage.GetAllData().Where(x
   => x.SubscriptionPackageID ==`enter code here` id && x.EmployerID==emp ).FirstOrDefault().ID);
               return getpackages;
           }

 1. var EmployerId = Convert.ToInt32(Session["EmployerId"]);
               var getpackage = GetPackage(employerSubscription.ID, EmployerId);
2

参考までに、テストプロジェクトなどで、EF MigrationsがDbを構成せずに実行しようとした場合にも、このエラーが発生する可能性があります。

クエリでエラーが発生していることがわかりましたが、クエリのためではなく、マイグレーションを開始してDbを作成しようとしたため、これを何時間も追跡しました。

1
Chris Moschini

@Mehmetが指摘しているように、結果が1要素以上を返す場合、顧客番号を共有している顧客が設計されていないため、データを調べる必要があります。

しかし、要点まで、私はあなたに簡単な概要を提供したかった。

//success on 0 or 1 in the list, returns dafault() of whats in the list if 0
list.SingleOrDefault();
//success on 1 and only 1 in the list
list.Single();

//success on 0-n, returns first element in the list or default() if 0 
list.FirstOrDefault();
//success 1-n, returns the first element in the list
list.First();

//success on 0-n, returns first element in the list or default() if 0 
list.LastOrDefault();
//success 1-n, returns the last element in the list
list.Last();

より多くのLinq式については System.Linq.Expressions をご覧ください

0
Martin Sax