Je souhaite créer un bouton de recherche qui permettrait à un utilisateur de rechercher un membre et de charger les détails associés. J'utilise également Ajax BeginForm.
Il y a 3 classes / tables:
public Book()
{
this.Loans = new HashSet<Loan>();
}
public int ISBN { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public int OnLoan { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Loan> Loans { get; set; }
}
Loan Class
public partial class Loan
{
public int LoanId { get; set; }
public System.DateTime CheckOutDate { get; set; }
public System.DateTime ReturnDate { get; set; }
public decimal FinePrice { get; set; }
public Nullable<int> MemberId { get; set; }
public Nullable<int> ISBN { get; set; }
public virtual Book Book { get; set; }
public virtual Member Member { get; set; }
}
Classe de membre:
public partial class Member
{
public Member()
{
this.Loans = new HashSet<Loan>();
}
public int MemberId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string PostCode { get; set; }
public int TelNo { get; set; }
public virtual ICollection<Loan> Loans { get; set; }
}
Dans mon contrôleur BHistory:
public ActionResult HistorySearch(string qh)
{
var history = Gethistory(qh);
return PartialView(history);
}
private List<Loan> Gethistory(string searchString)
{
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.ToList();
}
Donc, au moment où la recherche fonctionne correctement, elle renvoie le résultat correct, dans le navigateur l'utilisateur entre memberid et une liste de résultats apparaît. Cependant, je veux seulement que le dernier des résultats apparaisse. Pas une liste de résultats
Donc au lieu d'utiliser ToList (), je veux utiliser LastorDefault (), mais j'obtiens le message d'erreur: impossible de convertir Models.Loan en collections.generic.list.
J'ai donc édité la méthode d'action
private Loan Gethistory(string searchString)
{
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.LastorDefault();
Cependant, lorsque je l'exécute, j'obtiens le message d'erreur:
LINQ to Entities ne reconnaît pas la méthode 'Library1.Models.Loan LastOrDefaultLoan', et cette méthode ne peut pas être traduite en une expression de magasin.
En conclusion, comment puis-je faire apparaître le dernier des résultats, pas une liste.
Cette question est différente des questions qui font référence aux réponses avec l'utilisation de Last () ou LastorDefault () car ici même si nous passons à l'utilisation de OrderByDescending () et First () ou FirstorDefault (), la réponse / résultat ne fonctionnerait pas. L'erreur résidait également dans la possibilité de renvoyer une liste même lorsque je pensais que la réponse ne devrait pas renvoyer une liste
Merci
2 réponses
Le problème est que le modèle sur votre page recherche un List<Loan>
, et vous ne lui envoyez qu'un Loan
. Au moment où j'ai publié cette réponse, vous n'avez pas votre méthode de contrôleur ou votre vue dans le cadre de votre question, je changerais donc votre requête comme suit:
private List<Loan> Gethistory(string searchString)
{
var loan = db.Loans
.Where(a => a.MemberId
.ToString()
.Contains(searchString) &&
a.Book.OnLoan == 1)
.OrderByDescending(a => a.LoanId)
.FirstOrDefault();
return new List<Loan> { loan };
}
Comme Stefan l'a dit dans sa réponse, SQL n'a pas de méthode LastOrDefault
, vous devez donc écrire votre requête d'une manière qui soit plus facile pour EF à convertir en SQL.
Alternativement, vous pouvez changer votre vue pour avoir un modèle qui est un seul prêt, bien que cela rendrait la grille (présumée) que vous les affichez / elle un peu moins intuitive.
Essaye ça:
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.OrderByDescending(c => c.MemberId)
.FirstOrDefault();
SQL ne comprend pas LastOrDefault
Vous devrez donc commander la liste. En utilisant OrderByDescending
, vous inverserez cet ordre et, par conséquent, pourrez prendre le meilleur record.
Si vous souhaitez toujours transmettre une collection, vous pouvez également utiliser le OrderByDescending
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.OrderByDescending(c => c.MemberId);
Voir LINQ To Entities ne reconnaît pas la méthode Last. Vraiment? pour plus de détails.
Ou cette question similaire:
supprimer un enregistrement avec un enfant
De nouvelles questions
c#
C # (prononcé "see sharp") est un langage de programmation multi-paradigme de haut niveau, typé statiquement développé par Microsoft. Le code C # cible généralement la famille d'outils et d'exécutions Microsoft .NET, notamment le .NET Framework, .NET Core et Xamarin. Utilisez cette balise pour les questions sur le code écrit en C # ou en spécification formelle de C #.