0

我正在构建一个 ASP.NET 应用程序,它将查询捕获产品中的制造错误的三个表之一。当然,每个表都反映在一个 EF 实体中。在提交页面并设置一个标志来指示要查询哪些错误之前,不会确定将查询哪个表。

这三个实体中的每一个都有许多共同的属性。这些共性已在接口中定义并由实体实现(通过部分类定义)。所以那些部分类看起来像......

public partial class ProductException : IExceptionEntity { }
public partial class PartException : IExceptionEntity { }
public partial class RebuildException: IExceptionEntity { }

在存储库类中,我定义了一个通用方法,允许我查询我指定的异常实体。这是必要的,因为 WHERE 子句作为参数传入方法,可能包含未在接口中定义的字段,并且特定于单个异常实体(产品、部件和重建)。所以称那些看起来像..

IQueryable<ProductException> prodQuery = Repository.GetFilteredQuery<ProductException>(query, whereClause);
IQueryable<PartException> partQuery = Repository.GetFilteredQuery<PartException>(query, whereClause);
IQueryable<RebuildException> rebuildQuery = Repository.GetFilteredQuery<RebuildException>(query, whereClause);

网页永远不会定义一个查询,并且无论查询结果如何,它对查询结果的处理方式都非常相似,因此我希望能够分配一个变量/属性,可以用于访问查询/结果,无论查询的是哪个实体。像下面的东西......

    protected override void OnPreLoad(EventArgs e)
    {
         InitializeExceptionQuery();
    }


    List<IExceptionEntity> _exceptionList = null;
    public List<IExceptionEntity> ExceptionList
    {
        get 
        { 
            if(_exceptionList == null)
                _exceptionList = LookupQuery.ToList();

            return _exceptionList;
        }
    }


    IQueryable<IExceptionEntity> _query = null;
    public IQueryable<IExceptionEntity> LookupQuery
    {
        get 
        { 
            if(_query == null)
                _query = GetExceptionQuery(this.ExceptionCategory); 

            return _exceptionList;
        }
        set
    { this._query = value; }
    }



    private void InitializeExceptionQuery()
    {
        String whereClause = "Filters defined here from user control properties.";

        switch (this.ExceptionCategory)
        {
            case ExceptionCategories.Product:
                this.LookupQuery = base.Repository.GetFilteredQuery<ProductException>(this.LookupQuery, whereClause, this.SortField, this.SortDirection).Cast<IExceptionEntity>();
                break;
            case ExceptionCategories.Part:
                this.LookupQuery = base.Repository.GetFilteredQuery<PartException>(this.LookupQuery, whereClause, this.SortField, this.SortDirection).Cast<IExceptionEntity>();
                break;
            case ExceptionCategories.Rebuild:
                this.LookupQuery = base.Repository.GetFilteredQuery<RebuildException>(this.LookupQuery, whereClause, this.SortField, this.SortDirection).Cast<IExceptionEntity>();
                break;
            case ExceptionCategories.UNKNOWN:
                throw new ArgumentException("Exception Category is undefined");
        }
    }


    private void BindQueryResults()
    {

        switch (this.ExceptionCategory)
        {
            case ExceptionCategories.Product:
                listView.DataSource = this.ExceptionList.Cast<ProductException>();
                listView.DataBind(); 
                break;
            case ExceptionCategories.Part:
                listView.DataSource = this.ExceptionList.Cast<PartException>();
                listView.DataBind();
                break;
            case ExceptionCategories.Rebuild:
                listView.DataSource = this.ExceptionList.Cast<RebuildException>();
                listView.DataBind();
                break;
            case ExceptionCategories.UNKNOWN:
                throw new ArgumentException("Exception Category is undefined");
        }
    }

整个目标是我希望能够调用 ExceptionList 属性,将其转换为实现 IExceptionEntity 接口的类型之一,瞧!无论我要查询的三个实体中的哪一个,都有一个点可以从中检索结果……即参见 BindQueryResults()。

然而,事实并非如此。当我运行它时,ExceptionList 属性在尝试将 Query 转换为列表 (.ToList()) 时抛出异常

Unable to cast the type 'PartException' to type 'IExceptionEntity'. LINQ to Entities only supports casting EDM primitive or enumeration types. 

我认为您可以根据需要来回转换接口和实现它的类。显然情况并非如此,我认为这是有道理的,但是还有其他方法可以完成我想要做的事情吗?我必须相信有。其他人有同样的难题吗?

谢谢你,G

更新:2013-01-22

我的印象是,如果我从基类而不是接口派生,我将能够将 ExceptionList 从基类转换为派生类,然后再返回。

为此,我一直在遵循 HighCores 的建议。我有 ...

  • 在概念模型 (EDMX) 中创建一个实体,其中包含三个“异常”实体(ProductException、PartException、RebuildException)之间共享的所有属性。我将其命名为“ExceptionBase”
  • 从三个异常扩展中删除了这些字段并从“ExceptionBase”派生它们

我现在遇到的问题是每个异常实体与其基础表之间的映射被破坏了。我需要将基类中的字段映射到派生实体的基础表。我希望能够在“映射详细信息”窗口中从基类中选择值/属性以映射到相应的表列,但是唯一可用的值是派生类的值,而不是基类的值班级。

更新:2013-01-23

事实证明,我使用的概念模型使用 TPT(按类型表策略),这就是以这种方式实现继承不起作用的原因。必须将公共字段拆分到数据库中自己的表中,以便我从它们继承。不幸的是,数据库模式无法更改。

我参考了以下文章,希望有人也会觉得有用:

因此,如果有人有任何其他想法,我仍在寻找一种方法来实现这一点,我欢迎任何进一步的建议。

更新:2013-01-23

谢谢马修的回复!我的表结构看起来像......

产品异常

  • 身份证 [PK]
  • 产品名称
  • 异常消息
  • 异常服务

零件异常

  • 身份证 [PK]
  • 零件名称
  • 零件制造商
  • 零件成本
  • 产品编号 [FK]
  • 异常消息
  • 异常服务

重建异常

  • 身份证 [PK]
  • 重建原因
  • 重建制造商
  • 产品编号 [FK]
  • 异常消息
  • 异常服务

基本上我想创建一个带有 ExceptionMsg、ExceptionSev 和 ID(?) 的 BaseEntity,因为这些字段由所有三个异常实体共享。


注意:是否有人否决了这篇文章,请提供解释?只有当我能从错误中吸取教训时,投反对票才有用,以免重蹈覆辙。

4

0 回答 0