将IEnumerable<Inherited>转换为IEnumerable<Base>

3

我想将一个继承类型的 IEnumerable 转换为基类的 IEnumerable

尝试了以下方法:

var test = resultFromDb.Cast<BookedResource>();

return test.ToList();

但是出现了错误:

您不能转换这些类型。Linq to Entities 只支持转换基元 EDM 类型。

涉及到的类如下:

public partial class HistoryBookedResource : BookedResource
{
}

public partial class HistoryBookedResource
{
    public int ResourceId { get; set; }
    public string DateFrom { get; set; }
    public string TimeFrom { get; set; }
    public string TimeTo { get; set; }
}

public partial class BookedResource
{
    public int ResourceId { get; set; }
    public string DateFrom { get; set; }
    public string TimeFrom { get; set; }
    public string TimeTo { get; set; }
}

[MetadataType(typeof(BookedResourceMetaData))]
public partial class BookedResource
{
}

public class BookedResourceMetaData
{
    [Required(ErrorMessage = "Resource id is Required")]
    [Range(0, int.MaxValue, ErrorMessage = "Resource id is must be an number")]
    public object ResourceId { get; set; }

    [Required(ErrorMessage = "Date is Required")]
    public object DateFrom { get; set; }

    [Required(ErrorMessage = "Time From is Required")]
    public object TimeFrom { get; set; }

    [Required(ErrorMessage = "Time to is Required")]
    public object TimeTo { get; set; }
}

我要解决的问题是使用Entity Framework和LINQ从表HistoryBookedResource获取记录,并将结果放入IEnumerable<BookedResource>中。
更新:
当使用以下代码进行转换时,强制转换似乎有效,但是在尝试使用foreach循环时,数据会丢失。
resultFromDb.ToList() as IEnumerable<BookedResource>;

更新2:

我正在使用实体框架生成的模型。该模型(edmx)是从数据库创建的,并包含表示数据库表的类。

在数据库中,我有一个旧的BookedResource历史记录表,用户可能想查看其中的数据。为了从数据库获取旧数据,实体框架使用与表同名的类来接收数据。因此,我将从HistoryBookedResource表中接收数据,并存储到HistoryBookedResource类中。

由于实体框架生成了带有属性的局部类,我不知道是否可以使它们虚拟并重写。

非常感谢任何建议。


1
有两个完全相同的类BookedResourceHistoryBookedResource有什么意义? - VladL
你正在影子资源,所以在执行转换后,你将无法再读取数据。 (此外,你不是从 IEnumerable<Inherited> 转到 IEnumerable<Base>,而是从 IQueryable<Inherited> 转到 IQueryable<Base> - Scott Chamberlain
没错,数据确实消失了,但是首先在我使用foreach时。您能否详细说明一下“阴影处理”是什么意思,以及为什么它是IQueryable而不是IEnumerable? - MikeAlike234
你在父类和子类中声明了相同的属性,但没有使用关键字override,这会导致shadowing。为了解决这个问题,必须在父类中将每个属性标记为virtual,并在子类中将每个属性标记为override。此外,从你得到的错误信息来看,我敢打赌resultFromDb是一个IQueryable<BookedResource>,这就是我所说的。你能解释一下为什么BookedResourceHistoryBookedResource中有相同的属性吗?HistoryBookedResource是否应该是某种DTO? - Scott Chamberlain
查看更新,需要长时间的评论。 - MikeAlike234
2个回答

6

通常在这种情况下,您需要使用AsEnumerable<T>

var test = resultFromDb.AsEnumerable().Cast<BookedResource>();

这样做的好处在于不会一次性列举出整个结果(你不会失去惰性)。


4

尝试使用以下方法:

resultFromDb.AsEnumerable().Cast<BookedResource>();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接