我想在我写的通用MVC视图中显示一个名为CriminalEvent
的实体。视图要求模型传递给它应实现IDataModel
接口。现在,CriminalEvent
具有实现此接口的属性,但名称不同,我无法更改。
因此,在我的代码中,我继承了CriminalEvent
和我的派生类(也称为CriminalEvent,我想这很愚蠢,但允许我避免许多代码更改...)具有显式接口代码:
Using ViewApp;
public interface IDataModel
{
int ID { get; set; }
int CriminalEventID { get; set; }
}
public class ViewCriminalEvent : AIM.Police.DB.CriminalEvent, IDataModel
{
int IDataModel.ID
{
get { return CriminalEventID; }
set { CriminalEventID = value; }
}
}
(我知道,在这种情况下,接口的ID属性等于CriminalEventID,它没关系)
我希望能够阅读AIM.Police.DB.CriminalEvent
实体并将我的视图模型由Linq填充到Entities Cast(),将它们添加到派生的CriminalEvent
,如下所示:
视图模型(我需要填充CriminalEvents
属性):
Using ViewApp;
public class CriminalEventMainViewModel
{
public IEnumerable<IDataModel> CriminalEvents { get; set; }
public IDataModel SelectedEntity { get; set; }
public string SubEntityDisplayName { get; set; }
public IEnumerable<IDataModel> SubEntityCollection { get; set; }
public IDataModel SelectedSubEntity { get; set; }
}
和Controller代码:
Using ViewApp;
private ViewResult CriminalEventIndexView(CriminalEvent selectedCriminalEvent = null)
{
CriminalEventMainViewModel viewModel =
new CriminalEventMainViewModel();
using (var db1 = new AIM.Police.DB.InvestigationContext(lazyLoadingEnabled: false))
{
viewModel.CriminalEvents = db1.CriminalEvents.Cast<ViewCriminalEvent>().ToList(); // THIS LINE THROWS THE EXCEPTION
viewModel.SelectedEntity = selectedCriminalEvent;
}
return View("Index", (object)viewModel);
}
请注意原始的CriminalEvent
类和InvestigationContext
都在AIM.Police.DB dll中找不到我无法触及
错误:
Unable to cast the type 'AIM.Police.DB.CriminalEvent' to type 'InvestigationSimulator.Models.CriminalEvent'. LINQ to Entities only supports casting EDM primitive or enumeration types.
为什么会出现此错误? 我的方法备注总是受欢迎的。
答案 0 :(得分:3)
由于您获得了所有实体,因此可以先实现查询,然后执行转换。
这将执行内存中的强制转换,而不是尝试将其作为查询转换的一部分进行表达。之所以出现此错误,是因为LINQ to Entities不支持将SQL转换为非实体类,即使它是从实体类继承的,因为没有将其他列映射到SELECT
语句。通过实现数据,然后在内存中执行Cast
(LINQ to Objects),可以避免转换错误。
但是,在您的情况下,您可以向后继承这项工作。为了使其工作,我建议让数据库模型实现IDataModel
并完全避免强制转换,请参阅http://msdn.microsoft.com/en-us/library/vstudio/bb738696(v=vs.100).aspx和http://msdn.microsoft.com/en-us/library/wa80x488.aspx。特别是,你的部分类可以实现接口(老实说,不记得设计者是否允许你添加接口定义,因为我现在只做代码优先)。请注意,可能完全不需要您的视图特定模型。
viewModel.CriminalEvents = db1.CriminalEvents.ToList();
我可能会做的另一种选择是保持视图模型完全分离(不要让它继承实体类)并使用AutoMapper在它们之间进行映射。
var criminalEvents = db1.CriminalEvents.ToList();
viewModel.CriminalEvents = Mapper.Map<CriminalEventViewModel>(criminalEvents);
答案 1 :(得分:2)
Enumerable.Cast<TResult>
正在尝试转换集合中的每个元素。它在你的场景中失败(毫不奇怪),因为你试图将父(AIM.Police.DB.CriminalEvent
)类的实例强制转换为 child 的对象({{1} })类。你不能用C#进行这样的演员。
为了解决这个问题,您需要先从数据库加载对象,然后将它们手动转换(映射)到您的Model类。最简单的代码是这样的:
InvestigationSimulator.Models.CriminalEvent
答案 2 :(得分:0)
在ToList()或Single()
之后使用强制转换_c.Customers.ToList().Cast<CustomerBinding>()