在 Linq 中将类转换为同一类的部分
本文关键字:一类 Linq 转换 | 更新日期: 2023-09-27 17:56:06
我在EF中作为实体的类是:
Cat { Id, ParentId, Name, ImageUrl, ...}
Tree { Id , ParentId, Name}
是否有其他选择:
var trees= (from rs in _db.ItemCats
where rs.ParentId == null
select new Tree
{
Id = rs.Id,
ParentId = rs.ParentId,
Name = rs.Name
}).ToList();
像这样:
var trees= (from rs in _db.ItemCats
where rs.ParentId == null
select new
{
rs.Id, rs.Name,
rs.ParentId
}).Cast<Tree>().ToList();
但得到:
无法将类型"匿名类型"转换为类型"Meha3.Models.Tree"。 LINQ to 实体仅支持强制转换 EDM 基元或枚举 类型
您要求的是"鸭子"类型,而 .Net 不支持"鸭子"类型,因此您无法直接强制转换它。 您的所有选项都包括通过映射、树上的构造函数、反射等将其转换为您想要的类型,但实际的强制转换是不可能的。
为指向其他 SO 答案的链接道歉,但我认为没有必要在这里复制详细信息......
转换选项在这里
此处为反射选项
斯基特的另一种方式,他特别说是可怕的......不要这样做...
我强烈建议使用转换方法或构造函数方法。
是的,有。但是,不像你的例子。您可能想查看自动映射器:
如果您使用它,您的问题将像这样解决:
Mapper.CreateMap<Cat, Tree>();
var tree = Mapper.Map<Tree>(cat);
不能从匿名类型强制转换为 Tree 类,因为匿名类型不属于树类型
您还违反了有关服务器端可以执行和不能执行的内容的各种 EF 规则
当我不得不执行类似的任务时,我最终不得不编写这样的代码 - 不优雅,但它有效:
var trees= (from rs in _db.ItemCats
where rs.ParentId == null
select new
{
Id = rs.Id,
Name = rs.Name,
ParentId = rs.ParentId
})
.AsEnumerable() //to run the query and take us out of the EF domain
.Select(a => new Tree()
{
Id = a.Id,
Name = a.Name,
ParentId = a.ParentId
})
.ToList();
你可以使用Lambada语法缩短一点,但不会缩短太多
像这样:
var trees= _db.ItemCats.Select(Cat => new Tree(){
Id = Cat.Id,
ParentId = Cat.ParentId,
Name = Cat.Name
}).ToList();
另一种选择是,如果您经常这样做,则可以将转换移动到扩展方法,这将允许您调用类似以下内容
var trees = _db.ItemCats.Select(Cat => Cat.ToTree()).ToList();