尝试通用/’免费’时出现问题| ASP MVC

有没有办法在C#中(在辅助类或其他东西中)只定义一个方法,而不知道返回哪种类型?

很长的解释我得到以下错误:

无法转换System.Data.Objects.ObjectQuery 1[WerkStageNu.Vacancies]' to type 'System.Linq.IQueryable类型的对象1[WerkStageNu.Vacancies]' to type 'System.Linq.IQueryable 1 [WerkStageNu.Models.IFilteredEntities]’。

我有一个ListingsController,它通过数据库中的当前职位空缺进行搜索:

 public ActionResult Search(int? page, string branchid, string hoursago, string jobtypeid, string educationlevelid, string careerlevelid) { string searchResult = string.Empty; const int pageSize = 10; IQueryable selectedListings = (IQueryable)Repository.Instance._entities.Vacancies.AsQueryable(); Dictionary filterParams = new Dictionary() { {"branchid", branchid}, {"hoursago", hoursago}, {"jobtypeid", jobtypeid}, {"educationlevelid", educationlevelid}, {"careerlevelid", careerlevelid}}; selectedListings = FilterByIDHelper.Filter(selectedListings, filterParams); var paginatedDinners = new PaginatedList(((IQueryable)selectedListings).ToList(), page ?? 0, pageSize); return View("Index", paginatedDinners); } 

现在,这个搜索仅适用于职位空缺。 但是可以想象我们在整个地方搜索所有通常都是相同的例程,因此我想调用相同的方法来获取不同的类型。 在这种情况下,我创建了一个Interface,IFilteredEntities。 在我的部分class级空缺职位(部分class级,职业空缺由我的数据库entity framework生成)我只是这样做:

 public partial class Vacancies : IFilteredEntities 

当然,实现接口中的方法,这些方法不是默认实现的。 在我的界面中我有:

  interface IFilteredEntities { string EducationLevelID { get; set; } string BrancheID { get; set; } string CareerLevelID { get; set; } string JobTypeID { get; set; } Branches Branches { get; set; } DateTime? DateOfCreation { get; set; } CareerLevels CareerLevels { get; set; } JobTypes JobTypes { get; set; } EducationLevels EducationLevels { get; set; } } 

为方便起见,我在这里和这里上传了两个辅助类PaginatedList和FilterCriteriaHelper。

现在,将进行实际过滤的方法放在另一个辅助类中:FilterByIDHelper.cs。

  public static IQueryable Filter(IQueryable collection, Dictionary filterParams) { if (filterParams.ContainsKey("branchid")) collection = FilterByBranchId(collection, filterParams["branchid"]); if (filterParams.ContainsKey("hoursago")) collection = FilterByHoursAgo(collection, filterParams["hoursago"]); if (filterParams.ContainsKey("jobtypeid")) collection = FilterByJobTypeId(collection, filterParams["jobtypeid"]); if (filterParams.ContainsKey("educationlevelid")) collection = FilterByEducationLevelId(collection, filterParams["educationlevelid"]); if (filterParams.ContainsKey("careerlevelid")) collection = FilterByCareerLevelId(collection, filterParams["careerlevelid"]); return collection; } public static IQueryable Filter(IQueryable collection, Dictionary filterParams) { if (filterParams.ContainsKey("branchid")) collection = FilterByBranchId(collection, filterParams["branchid"]); if (filterParams.ContainsKey("hoursago")) collection = FilterByHoursAgo(collection, filterParams["hoursago"]); if (filterParams.ContainsKey("jobtypeid")) collection = FilterByJobTypeId(collection, filterParams["jobtypeid"]); if (filterParams.ContainsKey("educationlevelid")) collection = FilterByEducationLevelId(collection, filterParams["educationlevelid"]); if (filterParams.ContainsKey("careerlevelid")) collection = FilterByCareerLevelId(collection, filterParams["careerlevelid"]); return collection; } 

为方便起见,这是我的解决方案资源管理器的一部分图片:

Solution Explorer http://www.bastijn.nl/zooi/solutionexplorer.png

简而言之:

我尝试做的不是调用:

 selectedListings = Repository.Instance._entities.Vacancies.AsQueryable(); Dictionary filterParams = new Dictionary() { {"branchid", branchid}, {"hoursago", hoursago}, {"jobtypeid", jobtypeid}, {"educationlevelid", educationlevelid}, {"careerlevelid", careerlevelid}}; selectedListings = FilterByIDHelper.Filter(selectedListings, filterParams); var paginatedDinners = new PaginatedList(selectedListings.ToList(), page ?? 0, pageSize); return View("Index", paginatedDinners); 

使用接口调用显示的变体,因此我只需要定义te“Filter”方法一次,而不是所有类/模型。 现在请注意,所有这些都要编译! 问题是我收到以下错误:

 Unable to cast object of type 'System.Data.Objects.ObjectQuery`1[WerkStageNu.Vacancies]' to type 'System.Linq.IQueryable`1[WerkStageNu.Models.IFilteredEntities]'. 

我希望我没有忘记任何信息,但我已经盯着这段代码了一段时间。 可能会忘记关系或某事,如果我这样做就问它:)。

————————————————– —

编辑后编辑

————————————————– —

O废话,没关系这部分,我忘了AsEnumerable,仍然使用AsQueryable。

在我看来,这是一个协方差与逆变问题。 基本上, IQueryable不是IQueryable的子类型,即使Vacancies实现了IFilteredEntities。 因此,具有强制转换的行会导致运行时错误。 所以,而不是做演员而不是尝试:

 IEnumerable selectedListings = Repository.Instance._entities.Vacancies.AsQueryable() .OfType(); 

这将做的是将集合的每个元素投影到IFilteredEntities类型。

另一个选择是重写您的filter方法,以便它们使用generics,如下所示:

 public static IEnumerable Filter( IEnumerable collection, IDictionary filterParams) where T : IFilteredEntities { ... } 

然后,这将允许您传入包含从IFilteredEntities派生的任何类型的集合,并返回相同类型的集合。 如果你正在使用C#3,如果编译器可以隐式确定它,你甚至不必指定类型参数。