我想创建一个搜索按钮,使用户可以搜索成员并加载相关的详细信息。我也在使用Ajax BeginForm。
有3个类/表:
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; }
}
会员类:
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; }
}
在我的BHistory Controller中:
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();
}
所以目前搜索工作正常,它会返回正确的结果,在浏览器中用户输入memberid并显示结果列表。但是我只希望显示最后一个结果。不是结果列表
所以我没有使用ToList(),而是想使用LastorDefault(), 但我收到错误信息: 无法将Models.Loan转换为collections.generic.list。
所以我编辑了ActionMethod
private Loan Gethistory(string searchString)
{
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.LastorDefault();
然而,当我运行这个时,我收到错误消息:
LINQ to Entities无法识别方法&#39; Library1.Models.Loan LastOrDefaultLoan&#39;方法,并且此方法无法转换为商店表达式。
总之,如何才能显示最后一个结果,而不是列表。
这个问题与使用Last()或LastorDefault()引用答案的问题不同,因为即使我们切换到使用OrderByDescending()和First()或FirstorDefault(),答案/结果也不起作用。 即使我认为答案不应该返回列表
,该错误也会导致返回列表的能力由于
答案 0 :(得分:3)
问题在于您网页上的模型正在寻找List<Loan>
,而您只是发送Loan
。截至发布此答案时,您没有将控制器方法或视图作为问题的一部分,因此我会将您的查询更改为:
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 };
}
正如Stefan在回答中所说,SQL没有LastOrDefault
方法,因此您需要以更容易让EF转换为SQL的方式编写查询。
或者,您可以将视图更改为具有单个贷款的模型,但这会使(可推测的)网格显示它们/它更不直观。
答案 1 :(得分:1)
试试这个:
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.OrderByDescending(c => c.MemberId)
.FirstOrDefault();
SQL无法理解LastOrDefault
所以,你需要订购清单。通过使用OrderByDescending
,您将反转此顺序,因此可以获得最高记录。
如果您仍想传递集合,也可以使用OrderByDescending
return db.Loans
.Where(a => a.MemberId.ToString().Contains(searchString) && a.Book.OnLoan == 1)
.OrderByDescending(c => c.MemberId);
有关详细信息,请参阅LINQ To Entities does not recognize the method Last. Really?。
或类似的问题:
答案 2 :(得分:0)
使用.LastOrDefault(...)代替.where
返回db.Loans 。 LastOrDefault (a =&gt; a.MemberId.ToString()。包含(searchString)&amp;&amp; a.Book.OnLoan == 1);
它还可以提高您的表现。