首页 > 解决方案 > Icollection 不包含任何

问题描述

美好的一天,我正在编写代码,使用即时加载来加载Assigned使用该Include方法的相关数据。我正在尝试获取 的值IsAvailable,以便从中访问数据Assigned并检查是否有值ReturnDate等于 null 的记录。我不断收到错误消息

Icollection 不包含任何

public ActionResult Index()
    {
        var item = db.Item.Include(h => h.Assigned).Select(b => new ItemViewModel
        {
            ItemID = b.ItemID,
            ItemName = b.ItemName,
            Category = b.Category,
            Description = b.Description,
            Model = b.Model,
            IsAvailable = !b.Assigned.Any(h => h.ReturnDate == null)
        }).ToList();

        return View(item);
    }

项目视图模型

public class ItemViewModel
{

    public int ItemID { get; set;}
    [Display(Name = "Item")]
    public string ItemName { get; set; }
    [Required(ErrorMessage = "Category is required")]
    public string Category { get; set; }
    public string Model { get; set; }
    public string Description { get; set; }
    public bool IsAvailable { get; set; }
}

物品类别

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Collections;

    namespace Inventoryproto3.Models
    {
        public class Item
        {

            public int ItemID { get; set; }
            [Required(ErrorMessage ="Please enter a title"),Display(Name ="Item")]
            public string ItemName { get; set;}
            [Required(ErrorMessage ="Category is required")]
            public string Category { get; set;}
            public string Model { get; set;}
            public string Description{get; set;}

            public ICollection Assigned { get; set; }


        }
    }

“System.Collections.Generic.ICollection”不包含“Any”的定义,并且找不到接受“System.Collections.Generic.ICollection”类型的第一个参数的可访问扩展方法“Any”(您是否缺少使用指令或程序集参考?

错误截图

标签: asp.net-mvcentity-frameworklinqmodel-view-controller

解决方案


每个Item都有一个属性Assigned,它是 type ICollection

如果您查看Queryable.Any的定义,您会发现:

public static bool Any<TSource> (this IQueryable<TSource> source, 
       Expression<Func<TSource,bool>> predicate);

因此,属性Assigned应该实现ICollection<TSource>其中 TSource 是您希望在集合中找到的实际类型。

正确的解决方案是更改 property 的类型Assigned,这样您就知道该集合仅包含您期望的类型的项目。唉,你选择给我们很多不重要的信息,但是你忘了提到 中的项目类别Assigned,所以我们假设它是 type MyClass

class MyClass
{
    public Datetime ReturnDate {get; set;}
    ...
}

class Item
{
     ...
     public ICollection<MyClass> Assigned {get; set;}
}

这将解决您的问题:Any(...)有效,并且您确定人们只能将MyClass对象放入集合中。

如果您不想将集合限制为 MyClass 对象,您至少可以将自己限制为具有属性的类ReturnDate

interface IMyInterface
{
    public Datetime ReturnDate {get; set;}
}

class Item
{
     ...
     public ICollection<IMyInterface> Assigned {get; set;}
}

如果你真的希望人们可以MyClass在集合中添加除对象之外的其他东西,我强烈建议不要这样做,你必须指定你想要的:

  • 忽略集合中不是 MyClass 对象的项目?利用OfType
  • 只是希望没有人在收藏中放过其他东西吗?使用Cast,但话又说回来:为什么不防止有人在类中放置不正确的对象并定义ICollection<MyClass>

OfType可能不起作用AsQueryable,在这种情况下,您应该使用 将数据移动到本地进程AsEnumerable。为 ICollection 权限使用正确类型的第三个原因。

IsAvailable = !b.Assigned.OfType<MyClass>().Any(h => h.ReturnDate == null);
IsAvailable = !b.Assigned.Cast<MyClass>().Any(h => h.ReturnDate == null);

第一个将忽略您收藏的其他类型的项目。如果您的集合中有另一种类型,后者将引发异常(使其成为ICollection<MyClass>


推荐阅读