CAST()异常:LINQ到实体仅支持铸造EDM元或枚举类型 [英] Cast() exception: LINQ to Entities only supports casting EDM primitive or enumeration types

查看:298
本文介绍了CAST()异常:LINQ到实体仅支持铸造EDM元或枚举类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要显示我写了一个通用的MVC视图名为 CriminalEvent 的一些实体。视图要求模型传递给它应执行 IDataModel 接口。现在, CriminalEvent 必须实现这个接口,但以不同的名称属性,我不能改变它。

I want to display some entity named CriminalEvent in a general-purpose MVC view I wrote. The view requires that the Model pass to it shall implement the IDataModel interface. Now, CriminalEvent has the properties to implement this interface but under a different name and I cannot change it.

所以在我的code我继承了 CriminalEvent 和我的派生类(也称为CriminalEvent,愚蠢的我猜,但可以让我避免许多code的变化。 ..)具有显式接口code:

So in my code I inherited CriminalEvent and my derived class (also called CriminalEvent, stupid I guess but allows me to avoid many code changes...) has explicit interface code:

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,这是确定的)

(I know, in this case the interface's ID property equals CriminalEventID, it's Ok)

我希望能够读 AIM.Police.DB.CriminalEvent 实体和LINQ的填充我的观点模型)ING它们派生铸造实体( CriminalEvent ,就像这样:

I expected to be able to read the AIM.Police.DB.CriminalEvent Entities and populate my view model by Linq to Entities Cast()ing them to the derived CriminalEvent, like this:

视图模型(我需要填充 CriminalEvents 属性):

The view model (I need to populate the CriminalEvents property):

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; }
}

和控制器code:

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发现我不能碰

Note both the original CriminalEvent class and the InvestigationContext are found in the AIM.Police.DB dll that I cannot touch

该错误:

无法转换类型'AIM.Police.DB.CriminalEvent为键入'InvestigationSimulator.Models.CriminalEvent。 LINQ到实体仅支持铸造EDM原始或枚举类型。

为什么我得到这个错误?
我的做法的言论总是受欢迎的。

Why do I get this error? Remarks on my approach are always welcome..

推荐答案

既然你得到的所有实体,你可以先兑现查询,然后执行转换。

Since you're getting all of the entities, you could materialize the query first, then perform the cast.

这将执行,而不是试图制定它作为查询翻译的一部分,在内存中的演员。该错误出现,因为LINQ到实体不支持改造SQL到非实体类,甚至当它从一个实体类继承,因为对于其他列的 SELECT 语句。通过物化的数据,然后在执行演员内存(LINQ到对象),您避免翻译错误。

This would perform the Cast in memory instead of trying to formulate it as part of the query translation. The error comes because LINQ to Entities doesn't support transforming the SQL to a non-entity class, even when it inherits from an entity class, because there is no mapping for the additional columns to the SELECT statement. By materializing the data, then performing the Cast in memory (LINQ to Objects), you avoid the translation error.

不过,在你的情况,你有继承向后这个工作。它的工作,我建议具有DB模式实施 IDataModel 并完​​全避免的演员,看的 http://msdn.microsoft.com/en-us/library/vstudio/bb738696(v = VS.100 )的.aspx http://msdn.microsoft.com/en -us /库/ wa80x488.aspx 。特别是,你的部分类可以实现接口(真的不记得,如果设计允许你添加一个接口定义,因为我只做code-第一这些天)。请注意,可能会删除您的观点特定未尽型号的需求。

However, in your case, you have the inheritance backwards for this to work. For it to work, I'd suggest having the DB model implement IDataModel and avoid the cast entirely, see http://msdn.microsoft.com/en-us/library/vstudio/bb738696(v=vs.100).aspx and http://msdn.microsoft.com/en-us/library/wa80x488.aspx. In particular, your partial class can implement the interface (honestly don't remember if the designer allows you to add an interface definition since I only do code-first these days). Note that may remove the need for your view-specific model entirely.

viewModel.CriminalEvents = db1.CriminalEvents.ToList();

另一种选择,我可能会做的,就是保持视图模型完全独立的(没有它从实体类继承),并使用AutoMapper它们之间的映射。

The alternative, which I would probably do, is keep the view model completely separate (not have it inherit from the entity class) and use AutoMapper to map between them.

var criminalEvents = db1.CriminalEvents.ToList();
viewModel.CriminalEvents = Mapper.Map<CriminalEventViewModel>(criminalEvents);

这篇关于CAST()异常:LINQ到实体仅支持铸造EDM元或枚举类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆