icollection包含到ienumerable

vltsax25  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(214)

我不确定这个问题是否有意义。但是有人知道是否可以在linqlambda表达式中的.include表达式中进行类型转换吗。

var Items = _context.Items
        .Include(c => c.ItemCategorys)
        .ToList();

The navigation property is declared like an ICollection "public ICollection<ItemCategory> ItemCategorys { get; set; }"

问题是,我能否将icollection类型强制转换为“.include”语句中的ienumerable。
我试过但没有成功

var Items = _context.Items
        .Include(c => c.ItemCategorys.AsEnumerable())
        .ToList();

var Items = _context.Items
        .Include(c => c.ItemCategorys as IEnumerable<ItemCategorys>)
        .ToList();
8wigbo56

8wigbo561#

你必须理解include应该用来做什么。
根据规范,queryableextensions.include将包含完整的指定属性。人们经常用它作为“选择所有属性”的缩写。
假设学校和学生之间有一个简单的一对多关系:每个学校都有零个或多个学生,每个学生只上一个学校,即外键所指的学校。
如果学校[110]有2000名学生,那么学校[10]的每个学生都有一个值为10的外键。如果您使用include将school[10]与其学生一起取回,您将把相同的值转移10次,超过2000次。多浪费处理能力啊!
使用select来获取数据更明智:

var schools = dbContext.Schools.Select(school => new
    {
        // Select only the School properties that you plan to use
        Id = school.Id,
        Name = school.Name,
        ...

        Students = school.Students.Select(student => new
        {
            // again: only the properties that you plan to use
            Id = student.Id,
            Name = student.Name,
            ...

            // not needed, you know the value
            // SchoolId = student.SchoolId,
        })
        .ToList(),
    });

在实体框架中,始终使用select查询数据,并仅选择要使用的属性。仅当您计划更改获取的数据时才使用include。
不要用include来保护你的打字安全。
select的好处在于,您可以返回与源数据不同的数据,而源数据正是您想要的。
您想获取“项目的几个属性,每个项目都有其itemcategories的几个属性的可枚举序列”

var result = dbContext.Items.Select(item => new
{
    Id = item.Id,
    Name = item.Name,
    ...

    ItemCategories = item.ItemCategories.Select(category => new
    {
        Id = category.Id,
        ...
    });
})

请注意,itemcegories是某种匿名类型的iqueryable。如果你想的话 IEnumerable<ItemCategory> ,使用 .Select(category => new ItemCategory 只填充您计划使用的属性。
结果是 IQueryable<ItemCategory> .
积极的:如果你的来电者只想要几个itemcegories,你不会得到所有的。
否定:在获取所有所需元素之前,必须保持dbcontext的活动状态。
问题是用户不知道哪些属性是填充的,哪些没有。为了克服这一点,人们倾向于将内部数据结构(即dbset中的类)与您向其他人公开的数据分开:

.Select(category => new ExternalCategory()
{
     Id = category.Id,
     ...
});

这个方法的优点在于,您可以让不同的用户访问不同的值:一些用户只使用get属性获取数据,其他用户有更新数据的方法,超级用户有权更改表。
另外:通过将数据库结构与其他人可以访问的数据分离,您可以对数据库进行小的更改,而不必更改用户。

相关问题