2011-11-11 17 views
5

intenté tomar un registro y omitir el resto. mi código no arroja ningún error, pero no da ningún resultado. aquí está mi código así que por favor eche un vistazo y dígame qué está mal en mi código.LINQ Cómo tomar un registro y omitir el resto C#

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

    } 

Respuesta

4

Prueba esto código.

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]; 
9

si usted quiere tomar primer registro puede llamar a estos Take(1), First(), FirstOrDefault()

si usted quiere tomar 1 registro de la llamada media esto: Skip(n).Take(1) donde n - es el número de registros omitidos

Cuando se llama a Take(n) - no hay necesidad de llamar Saltar después de eso, ya han seleccionado los registros n

+0

distinción importante. 'Take' devuelve un' IEnumerable 'y' First' devuelve 'TSource'. – Jess

1

Si desea obtener sólo un registro, se debe reemplazar la llamada ToList final con First() o FirstOrDefault() están aquí sólo para este propósito. La diferencia entre dos métodos es First() arrojará una excepción si no hay nada que devolver (por ejemplo, colección vacía). Y FirstOrDefault() devolverá default(T) (por ejemplo, null para las clases y 0 para los tipos de valores).

2

No estoy seguro de lo que quiere decir con "tome uno y omita el resto", pero sospecho que está confundiendo el funcionamiento de las operaciones LINQ. Devuelven una secuencia nueva según los criterios que especificó, y esa nueva secuencia solo tiene exactamente lo que usted solicitó.

Por ejemplo, si tiene una Lista con tres elementos y llamó al Take(1), obtiene un IEnumerable con 1 artículo. No queda nada para "omitir" porque solo hay un elemento en su lista. Su tabla de datos original no se modifica: las secuencias LINQ son inmutables.

Suena como todo lo que realmente quiere hacer es:

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

Por supuesto, esto es una operación muy común en LINQ por lo que no es otra, algo así "más claro" para hacerlo:

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

Prefiero usar IQueryable en lugar de List.

De todos modos se puede utilizar Queryable.Skip saltarse el no de los elementos que necesita

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

También encontrará más información sobre esto en Return or Skip Elements in a Sequence (LINQ to SQL)

1

Romper el encadenamiento a continuación:

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

se convierte en:

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

Esto hace que sea más fácil ver el error. tmp0 es un enumerable que devolverá todas las filas posibles cuando se enumere. tmp1 es un enumerable que devolverá solo la primera fila en tmp0 (o menos si no hay suficientes filas).tmp2 es un enumerable que omitirá las primeras 2 filas en tmp1 (o menos si no hay suficientes filas) y luego devolverá el resto. Finalmente oPerson2 hace que estos enumerables realmente devuelvan sus resultados y los almacene en una lista.

De esto está claro que el error fue .Skip(2) porque está tomando una enumeración de un elemento y omitiendo hasta 2 y dejando el resto, lo que da como resultado una lista de elementos max (1 - 2, 0) = 0.

Deje fuera el Skip() y obtendrá lo que desea, ya que "tomar hasta 1" ya implica "omitir el resto".

Cuestiones relacionadas