Icollection不包含任何定义

时间:2019-03-18 21:45:50

标签: asp.net-mvc entity-framework linq model-view-controller

美好的一天,使用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);
    }

ItemViewModel

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'的定义,并且找不到可访问的扩展方法'Any'接受类型为'System.Collections.Generic.ICollection'的第一个参数(您是缺少using指令或程序集引用?

Screenshot of error

1 个答案:

答案 0 :(得分:0)

每个Item都有一个Assigned类型的属性ICollection

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

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

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

正确的解决方案是更改属性Assigned的类型,以使您知道该集合仅包含所需类型的项目。 las,您选择给我们提供了许多不重要的信息,但是您忘记提及Assigned中的项目类别,因此,我们假设其类型为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>

的第四个理由