【问题标题】:The model is of type List, but this dictionary requires IEnumerable [closed]该模型是 List 类型,但此字典需要 IEnumerable [关闭]
【发布时间】:2017-01-13 21:51:55
【问题描述】:

在我的控制器中,我有一个简单的 LINQ 查询:

var results = .....ToList();

然后,我想将“结果”传递给呈现网格的视图。它需要一个模型:

@model IEnumerable<XXXX.WebSite.Areas.BrokerDashboard.Models.AccountHBSearchItem>

我不认为这会是个问题,但我明白了:

传入字典的模型项是“System.Collections.Generic.List”类型,但该字典需要一个“System.Collections.Generic.IEnumerable”类型的模型项

这让我很困惑,因为从我读到的所有内容来看,List&lt;T&gt; 已经是IEnumerable&lt;T&gt;

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

【问题讨论】:

  • 能否请您发布整个查询以及MyModel 的定义?谢谢
  • 您可以将List&lt;T&gt; 传递给强类型为IEnumerable&lt;T&gt; 的视图。你的类型不同吗?
  • 我认为你可以做 foo.Objects.AsEnumerable();在您的 linq 语句中
  • 我已经发布了整个查询,并更新了@model 以显示真实的东西,减去客户的名称。谢谢!

标签: c# asp.net-mvc


【解决方案1】:

您的List&lt;T1&gt;IEnumerable&lt;T2&gt; 似乎有不同类型的泛型参数。从您的第二次尝试中,我看到您使用的是IEnumerable&lt;string&gt;,但型号是IEnumerable&lt;MyNamespace.MyModel&gt;。确保泛型参数相同。你可以通过

  • List&lt;MyNamespace.MyModel&gt;
  • IEnumerable&lt;MyNamespace.MyModel&gt;
  • IOrderedEnumerable&lt;MyNamespace.MyModel&gt;

都是合适的

【讨论】:

  • 好的,我明白你在说什么。我认为我明白了吗?我用更多细节更新了 OP,包括 @model 的全名
  • 我不应该说,“我想我没问题。”显然我没有……只是不确定我错过了什么。谢谢!
  • @CaseyCrookston 你有没有机会在不同的命名空间中有两个类AccountHBSearchItem?例如。一个在模型中,另一个来自数据层?
  • ...啊哈....事实上。让他们改变一下。
  • 正在改变,但与此同时,这有什么关系呢?我认为不同的名称空间不会引起问题
【解决方案2】:

.ToList 的返回类型将为&lt;T&gt;

这意味着&lt;T&gt; 可以是实现特定接口的任何东西,或者是特定的具体/抽象类。这取决于使用泛型并返回那些 &lt;T&gt; 对象的列表的类。

&lt;T&gt;上使用接口约束意味着你可以接受&lt;T&gt;(或List&lt;T&gt;)而不知道&lt;T&gt;实际上是什么类型的对象,但仍然根据接口与特定的属性或方法进行交互&lt;T&gt; 必须实现。

将在 Razor 视图中使用的 @model 指定为 xxx.AccountHBSearchItem 类型的 IEnumerable(您可以遍历的列表)。 然后,您可以从@model 访问AccountHBSearchItem 中可用的属性和方法。 例如:@model.AccountTransactionID, @model.LeadId

List&lt;T&gt; 不是List&lt;xxx.AccountHBSearchItem&gt; - 它可以是任何东西。因此,Razor 将无法访问您将在视图上用于输出的属性和方法,因为它不能保证 &lt;T&gt; 对象具有适合的接口。您可能会将List&lt;Animal&gt; 传递给视图,并且对xxx.AccountHBSearchItem 拥有的属性的任何访问都将失败(我希望!)因为Animal 不是xxx.AccountHBSearchItem

因此,为了解决这个问题,您可以在用于生成List&lt;T&gt; 的类中声明&lt;T&gt; 实现了您在生成视图时需要使用的接口。

假设接口需要以下属性(根据您的数据猜测);使用这些属性创建一个接口,用于所有将用作&lt;T&gt; 的类。

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&lt;xxx.IAccountHBSearchItem&gt;(接口)。

现在你可以生成例如不同账户类型的搜索结果,只要他们实现了这个接口,然后在同一个View上全部使用。

现在可以通过接口访问可用的属性和方法了。

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    • 2020-09-08
    • 1970-01-01
    • 2022-01-16
    相关资源
    最近更新 更多