시퀀스에 둘 이상의 요소가 있습니다.


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
Calvin,이 경우이 답변을 해결책으로 받아 들여야합니다
Dejan Milicic

24
-1 "문제는 SingleOrDefault를 사용 하고 있다는 것입니다 "-OP 를 수집 할 수있는 것은 고유해야하는 고객 ID를 찾는 SingleOrDefaultFirstOrDefault입니다. 따라서 실제로 . 또한 이것은 동일한 ID로 2 명의 고객을 추가 할 수 있음을 보여 주므로 실제로 OP의 데이터베이스 설계에 더 심각한 문제를 제기했습니다!
James

27
@James, OP는 내 대답이 정확하고 예외는 컬렉션에 SingleOrDefault작동 을 막는 하나 이상의 요소가 있음을 분명히 명시합니다 . 사실 수 있습니다 여기에 더 나은 데이터베이스 설계를하는 것이 가능하지만 영업이 아닌 -1 대답에에 주석으로 더 적절한 것 같다.
JaredPar

9
IMO의 근본적인 문제는 2 개의 고유 한 고객 ID가 데이터베이스에 추가 될 수 있음을 보여주기 때문에 궁극적으로 DB 설계입니다. SingleOrDefault메소드가 기대하는 것과 찾은 것 사이에 불일치가 있기 때문에 예외가 발생합니다. 그래서 당신의 대답이 예외를 멈추게하더라도, 그것은 실제로 문제를 해결하지 못합니다. 그것은 "감옥에서 나오지 않는"카드에 가깝기 때문에 -1입니다.
James

2
이것은 오해의 소지가 있습니다! 사용 SingleOrDefault은 컬렉션에 0 개 또는 1 개의 항목이있을 것으로 예상하고 매번 확인하려는 경우에 해당합니다.
Achilles

23

SingleOrDefault메서드는 Exception시퀀스에 둘 이상의 요소 가있는 경우를 throw합니다 .

의 검색어 GetCustomer가 일치하는 항목을 두 개 이상 찾는 것 같습니다. 따라서 쿼리를 구체화하거나 데이터를 확인하여 주어진 고객 번호에 대해 여러 결과를 얻는 이유를 확인해야합니다.


5
Use FirstOrDefault insted of SingleOrDefault..

SingleOrDefault는 SINGLE 요소를 반환하거나 요소가 없으면 null을 반환합니다. Enumerable에서 2 개의 요소가 발견되면보고있는 예외가 발생합니다.

FirstOrDefault는 찾은 FIRST 요소를 반환하거나 요소가 없으면 null을 반환합니다. 따라서 조건 자와 일치하는 요소가 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없이 실행하려고하는 경우에도이 오류가 발생할 수 있습니다.

쿼리에 오류가 있음을 확인하기 전에 몇 시간 동안 이것을 추적했지만 쿼리 때문이 아니라 마이그레이션이 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.