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


110

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();   
}

1
SQL Top()集約関数と同じtake <>を使用します.Take(1).SingleOrDefault();
Thein

回答:


254

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


8
カルバン、その場合、この答えを解決策として受け入れる必要があります
Dejan Milicic

24
-1 「問題はあなたがSingleOrDefaultを使用していることです」 -私が収集できるものから、OPは一意である必要がある顧客IDを探しています。したがって、SingleOrDefault実際にはより適切ですFirstOrDefault。また、同じIDで2人の顧客を追加できることを示しているため、これは実際にはOPのデータベース設計により深刻な問題を引き起こしています。
James

27
@ジェームズ、OPは私の答えは正しかったと述べ、例外はコレクションに複数の要素があるために機能SingleOrDefaultしないことを明確に示しています。確かに、ここでより良いデータベース設計を行うことは可能かもしれませんが、それはOPに関するコメントとしてより適切であり、回答に対する-1ではありません。
JaredPar 2010

9
IMOの根本的な問題は、最終的には2つの一意の顧客IDをデータベースに追加できることを示しているため、DB設計です。SingleOrDefaultメソッドが予期していることとメソッドが検出していることの間に不整合があるため、例外がスローされています。だからあなたの答えは例外を止めますが、私にとっては、それは実際には問題を解決しません、それはより多くの「刑務所から抜け出す」カードなので、-1です。
James

2
これは誤解を招く!SingleOrDefaultコレクションが0または1のアイテムを持ち、毎回これが発生するかどうかを確認したい場合に、その用途は次のようになります...
アキレスは、

23

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

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


5
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);

1

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

クエリでエラーが発生していることがわかる前に、これを何時間も追跡しましたが、クエリが原因ではなく、移行を開始してデータベースを作成しようとしたためです。


0

@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を参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.