2009-06-19 6 views
0

J'essaye d'écrire une méthode linq to sql qui gère le tri, la pagination et le filtrage pour une grille ajax. J'ai créé un employé de classe partielle qui a un TotalRecordCount, car j'ai besoin de le transmettre au javascript pour configurer le pager. Le problème est qu'il ne sera pas généré car je ne peux pas définir AnonymousType # 1.TotalRecordCount, il est en lecture seule. Pourtant, si je fais "sélectionner un nouvel employé", alors il lancera l'exception - "La construction explicite du type d'entité 'InVision.Data.Employee' dans la requête n'est pas autorisée.".Question Linq to SQL - spécification des colonnes puis modification de la colonne

est ici le code ...

public string GetPageJSON(string sortColumn, string sortDirection, int pageNumber, int pageSize, EmployeeSearch search) 
     { 
      var query = from e in db.Employees 
         select new 
         { 
          EmployeeID = e.EmployeeID, 
          FirstName = e.FirstName, 
          LastName = e.LastName, 
          LoginName = e.LoginName, 
          IsLockedOut = e.IsLockedOut, 
          TotalRecordCount = e.TotalRecordCount 
         }; 
      //searching. 
      if (search.FirstName.Length > 0) query = query.Where(e => e.FirstName.Contains(search.FirstName)); 
      if (search.LastName.Length > 0) query = query.Where(e => e.LastName.Contains(search.LastName)); 
      if (search.LoginName.Length > 0) query = query.Where(e => e.LoginName.Contains(search.LoginName)); 
      if (search.Status.Length > 0) query = query.Where(e => (search.Status == "Active" && !e.IsLockedOut) 
       || (search.Status == "Inactive" && e.IsLockedOut)); 
      //sorting. 
      query = query.OrderBy(sortColumn, sortDirection); 
      //get total record count. 
      int totalRecordCount = query.Count(); 
      //paging. 
      query = query.Skip((pageNumber - 1) * pageSize).Take(pageSize); 
      //set total record count. 
      var list = query.ToList(); 
      if (list.Count > 0) 
      { 
       list[0].TotalRecordCount = totalRecordCount; //throws exception 
      } 
      //return json. 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      return serializer.Serialize(list); 
     } 

Répondre

1

Vous souhaitez sélectionner les objets originaux plutôt que de les faire correspondre à de nouveaux objets (que ce soit du même type, ou un type anonyme).

Remplacer ceci:

var query = from e in db.Employees 
         select new 
         { 
          EmployeeID = e.EmployeeID, 
          FirstName = e.FirstName, 
          LastName = e.LastName, 
          LoginName = e.LoginName, 
          IsLockedOut = e.IsLockedOut, 
          TotalRecordCount = e.TotalRecordCount 
         }; 

Avec ceci:

var query = db.Employees.AsQueryable(); 

Puis, plus tard le remplacer:

var list = query.ToList(); 
if (list.Count > 0) 
{ 
    list[0].TotalRecordCount = totalRecordCount; 
} 

Avec ceci:

var list = from e in query 
      select new 
      { 
       EmployeeID = e.EmployeeID, 
       FirstName = e.FirstName, 
       LastName = e.LastName, 
       LoginName = e.LoginName, 
       IsActive = !e.IsLockedOut, 
       TotalRecordCount = totalRecordCount 
      }; 

Je pense que ça devrait être tout. Si le JavaScriptSerializer exige une List, assurez-vous de l'utiliser comme ceci: return serializer.Serialize(list.ToList());

+0

Merci, mais cela ne fonctionne pas parce que j'ai besoin de limiter les colonnes que je retourne afin que la taille du message soit plus petite, aussi parce qu'il commet des erreurs quand il essaie de saisir tout avec des erreurs comme "La chaîne doit être exactement un caractère" et des références circulaires. – Justin

+0

L'autre alternative que j'aurais évoquée (étant donné l'information que vous venez de me donner) serait de faire ce que j'ai ci-dessus, puis de le mapper à une collection de nouveaux objets juste avant la sérialisation. Cela aurait évité la nécessité d'une nouvelle classe, mais aurait également obligé linq à tirer dans tous les domaines de la DB, par opposition à l'ensemble limité que vous avez. –

+0

À quoi ressemblerait le code avec cette approche? J'aimerais me débarrasser de ces classes de vue supplémentaires! :) – Justin

1

J'ai fini en utilisant une classe de vue personnalisée pour obtenir ce travail ...

partial class EmployeeView 
    { 
     public int EmployeeID { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string LoginName { get; set; } 
     public bool IsActive { get; set; } 
     public int TotalRecordCount { get; set; } 
    } 

public string GetPageJSON(string sortColumn, string sortDirection, int pageNumber, int pageSize, EmployeeSearch search) 
     { 
      var query = from e in db.Employees 
         select new EmployeeView 
         { 
          EmployeeID = e.EmployeeID, 
          FirstName = e.FirstName, 
          LastName = e.LastName, 
          LoginName = e.LoginName, 
          IsActive = !e.IsLockedOut, 
          TotalRecordCount = 0 
         }; 
      //searching. 
      if (search.FirstName.Length > 0) query = query.Where(e => e.FirstName.Contains(search.FirstName)); 
      if (search.LastName.Length > 0) query = query.Where(e => e.LastName.Contains(search.LastName)); 
      if (search.LoginName.Length > 0) query = query.Where(e => e.LoginName.Contains(search.LoginName)); 
      if (search.Status.Length > 0) query = query.Where(e => (search.Status == "Active" && e.IsActive) 
       || (search.Status == "Inactive" && !e.IsActive)); 
      //sorting. 
      query = query.OrderBy(sortColumn, sortDirection); 
      //get total record count. 
      int totalRecordCount = query.Count(); 
      //paging. 
      query = query.Skip((pageNumber - 1) * pageSize).Take(pageSize); 
      //set total record count. 
      var list = query.ToList(); 
      if (list.Count > 0) 
      { 
       list[0].TotalRecordCount = totalRecordCount; 
      } 
      //return json. 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      return serializer.Serialize(list); 
     } 
Questions connexes