LINQ Как взять одну запись и пропустить отдых c # - PullRequest
5 голосов
/ 11 ноября 2011

Я пытался взять одну запись и пропустить остальные.мой код не выдает никакой ошибки, но не дает никакого вывода.вот мой кодпоэтому, пожалуйста, посмотрите и скажите мне, что не так в моем коде.

public sealed class Person
{
    public Person() { }
    public Person(string name,bool HQ) {
        this.Name = name;
        this.HQ = HQ;
    }

    private string _Name;
    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    private bool _HQ;
    public bool HQ
    {
        get { return _HQ; }
        set { _HQ = value; }
    }
}

  protected void btn_Click(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("Name",typeof(string));
        dt.Columns.Add("HQ", typeof(bool));

        DataRow dr = null;
        dr = dt.NewRow();
        dr["Name"]="Arijit";
        dr["HQ"]=true;
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        dr["Name"] = "Dibyendu";
        dr["HQ"] = false;
        dt.Rows.Add(dr);

        dr = dt.NewRow();
        dr["Name"] = "Tridip";
        dr["HQ"] = false;
        dt.Rows.Add(dr);


        List<Person> oPerson1 = (from c in dt.AsEnumerable()
            select new Person
            {
                Name = c.Field<string>("Name"),
                HQ = c.Field<bool>("HQ")
            }).Skip(1).Take(2).ToList();


        List<Person> oPerson2 = (from c in dt.AsEnumerable()
            select new Person
            {
                Name = c.Field<string>("Name"),
                HQ = c.Field<bool>("HQ")
            }).Take(1).Skip(2).ToList();

    }

Ответы [ 7 ]

9 голосов
/ 11 ноября 2011

если вы хотите сделать первую запись, вы можете назвать эти Take(1), First(), FirstOrDefault()

если вы хотите взять 1 запись в середине вызова, это: Skip(n).Take(1), где n - количество пропущенных записей

Когда вы звоните Take(n) - после этого не нужно звонить Skip, он уже выбрал n записей

4 голосов
/ 11 ноября 2011

Попробуйте этот код.

Person oPerson1 = (from c in dt.AsEnumerable()
select new Person
{
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
}).First(); //first person in a list


Person oPerson2 = (from c in dt.AsEnumerable()
select new Person
{
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
}).Skip(1).First(); //second person in a list

However this code can be rewritten to be clearer:

List<Person> persons = from c in dt.AsEnumerable()
select new Person
{
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
};

Person oPerson1 = persons[0];
Person oPerson2 = persons[1];
3 голосов
/ 11 ноября 2011

Я предпочитаю использовать IQueryable вместо List.

В любом случае вы можете использовать Queryable.Skip , чтобы пропустить необходимое количество элементов

   IQueryable<Person> oPerson2 = (from c in dt.AsEnumerable()
            select new Person
            {
                Name = c.Field<string>("Name"),
                HQ = c.Field<bool>("HQ")
            }).Skip(2).Take(1);

Также вы найдете больше об этом в Возврат или Пропуск элементов в последовательности (LINQ to SQL)

2 голосов
/ 11 ноября 2011

Я не уверен, что вы подразумеваете под "взять один и пропустить остальные", но я подозреваю, что вы путаете, как работают операции LINQ. Они возвращают новую последовательность на основе указанных вами критериев, и эта новая последовательность имеет только то, что вы просили.

Например, если у вас есть список с тремя элементами и вы назвали Take(1), вы получите IEnumerable с 1 элементом. Больше нечего пропустить, потому что в вашем списке только один элемент. Ваша исходная таблица данных осталась без изменений - последовательности LINQ неизменны.

Похоже, все, что вы действительно хотите сделать, это:

    List<Person> oPerson2 = (from c in dt.AsEnumerable()
        select new Person
        {
            Name = c.Field<string>("Name"),
            HQ = c.Field<bool>("HQ")
        }).Take(1).ToList();

Конечно, это очень распространенная операция в LINQ, поэтому есть еще один, несколько «более ясный» способ сделать это:

    Person oPerson2 = (from c in dt.AsEnumerable()
        select new Person
        {
            Name = c.Field<string>("Name"),
            HQ = c.Field<bool>("HQ")
        }).First();
1 голос
/ 11 ноября 2011

Затем разбиваем последовательность:

List<Person> oPerson2 = (from c in dt.AsEnumerable()
  select new Person
  {
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
  }).Take(1).Skip(2).ToList();

становится:

var tmp0 = (from c in dt.AsEnumerable()
  select new Person
  {
    Name = c.Field<string>("Name"),
    HQ = c.Field<bool>("HQ")
  });
var tmp1 = tmp0.Take(1);
var tmp2 = tmp1.Skip(2);
List<Person> oPerson2 = tmp2.ToList();

Это облегчает выявление ошибки.tmp0 является перечислимым, который будет возвращать каждую возможную строку при перечислении.tmp1 является перечислимым, который будет возвращать только первую 1 строку в tmp0 (или меньше, если строк недостаточно).tmp2 - это перечисляемое, которое пропускает первые 2 строки в tmp1 (или меньше, если строк недостаточно), а затем возвращает остальные.Наконец, oPerson2 заставляет эти перечислимые элементы возвращать свои результаты и сохраняет их в списке.

Из этого ясно, что ошибка была .Skip(2), потому что она брала одноэлементное перечисление, пропускала до 2 и оставляла остальныев результате получается список max (1 - 2, 0) = 0 элементов.

Оставьте Skip(), и вы получите то, что вы хотите, так как "взять до 1" уже влечет за собой "пропустить остальные».

1 голос
/ 11 ноября 2011

Если вы хотите получить только одну запись, вам следует заменить окончательный вызов ToList на First() или FirstOrDefault(), они здесь только для этой цели. Разница между двумя методами заключается в том, что First() будет выдавать исключение, если нечего возвращать (например, пустую коллекцию). И FirstOrDefault() вернет default(T) (например, ноль для классов и 0 для типов значений).

0 голосов
/ 29 ноября 2018

Также .First () может использоваться для достижения этого

List<X> xlist= XBusiness.GetAllX(xname.ToString());
X lastX = xlist.First();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...