在我的控制器中,我有一个简单的LINQ查询:
var results = .....ToList();
然后,我想将'结果'传递给呈现网格的视图。它需要一个模型:
@model IEnumerable<XXXX.WebSite.Areas.BrokerDashboard.Models.AccountHBSearchItem>
我不认为这会有问题,但我明白了:
传递到字典中的模型项的类型为'System.Collections.Generic.List,但此字典需要类型为'System.Collections.Generic.IEnumerable
的模型项
这让我感到困惑,因为从我正在阅读的所有内容来看,List<T>
已经是IEnumerable<T>
。
根据答案here,我尝试了这个:
IEnumerable<string> eResults = results.ToList();
但是这让我感到Can implicitly convert
错误。
如果我不执行.ToList()
,那么results
是一个IOrderedEnumerable,我明白了:
传递到字典中的模型项的类型为'System.Linq.OrderedEnumerable,但此字典需要类型为'System.Collections.Generic.IEnumerable
的模型项
修改
这是整个查询:
var results = Context.GetLeadSalesAccountTransactions(accountID)
.OrderBy(a => a.TransactionDate)
.Select(a =>
{
currentTotal -= a.Debit != null ? (decimal)a.Debit : 0;
currentTotal += a.Credit != null ? (decimal)a.Credit : 0;
return new AccountHBSearchItem
{
AccountTransactionID = a.AccountTransactionID,
LeadID = a.LeadSales != null ? a.LeadSales.Lead.LeadID : 0,
Address = a.LeadSales != null ? a.LeadSales.Lead.Address : string.Empty,
LotNumber = a.LeadSales != null ? a.LeadSales.Lead.LotNumber : string.Empty,
Type = a.AccountTransactionType.GetDisplayName(),
Debit = a.Debit,
Credit = a.Credit,
RemainingBalance = currentTotal,
TransDate = a.TransactionDate
};
}
).OrderByDescending(i => i.TransDate).ToList();
答案 0 :(得分:2)
好像您有List<T1>
和IEnumerable<T2>
的不同类型的通用参数。从您的第二次尝试开始,我发现您使用的是IEnumerable<string>
,但模型是IEnumerable<MyNamespace.MyModel>
。确保通用参数相同。你可以通过
List<MyNamespace.MyModel>
IEnumerable<MyNamespace.MyModel>
IOrderedEnumerable<MyNamespace.MyModel>
所有这些都是合适的
答案 1 :(得分:0)
.ToList的返回类型将是<T>
类型。
这意味着<T>
可以是实现特定接口的任何东西,也可以是特定的具体/抽象类。这取决于使用泛型的类并返回那些<T>
对象的列表。
在<T>
上使用接口约束意味着您可以接受<T>
(或List<T>
),而不知道对象<T>
的实际类型,但仍然可以与之交互根据{{1}}必须实现的接口的特定属性或方法。
将在Razor View中使用的<T>
指定为@model
类型IEnumerable
(您可以迭代的列表)xxx.AccountHBSearchItem
。
然后,您可以从AccountHBSearchItem
访问@model
中可用的属性和方法。
例如:@model.AccountTransactionID, @model.LeadId
等
但List<T>
不是List<xxx.AccountHBSearchItem>
- 它可能是任何东西。因此,Razor将无法访问您将在View for output上使用的属性和方法,因为它无法保证<T>
对象具有适合的接口。您可以将List<Animal>
传递给视图,对xxx.AccountHBSearchItem
所拥有的属性的任何访问都将失败(我希望!),因为Animal
不是xxx.AccountHBSearchItem
}。
因此,要解决此问题,您可以在用于生成List<T>
的类中声明<T>
实现生成View时需要使用的接口。
假设接口需要以下属性(从您的数据中猜出);创建一个包含这些属性的接口,用于将用作<T>
的所有类。
public interface IAccountHBSearchItem
{
long AccountTransactionID { get; set; }
long LeadID { get; set; }
string Address { get; set; }
string LotNumber { get; set; }
string Type { get; set; }
bool Debit { get; set; }
bool Credit { get; set; }
decimal RemainingBalance { get; set; }
DateTime TransDate { get; set; }
}
现在指定不同的类实现此接口:
public class AccountSearchAAA<T> where T : IAccountHBSearchItem
{
// Rest of implementation
public List<T> GetAll()
{
// return list of AccountSearchAAA objects here
}
}
public class AccountSearchBBB<T> where T : IAccountHBSearchItem
{
// Rest of implementation
public List<T> GetAll()
{
// return list of AccountSearchBBB objects here
}
}
然后,您可以将@model
更改为使用IEnumerable<xxx.IAccountHBSearchItem>
(界面)。
现在,您可以生成不同帐户类型的搜索结果,只要它们实现此界面,然后在同一个视图中使用它们。
现在可以通过界面访问可用的属性和方法了。