我有一个与此问题类似的问题:linq question: querying nested collections
我有一个带有 a 的产品ICollection<Category>
,我想通过 id 获取一个类别。我通过 IProductsRepository 完成所有工作。
我已经尝试过这两种方法products.SelectMany(p => p.Categories).Where(c => c.CategoryID == categoryId)
以及我自己尝试过的products.SelectMany(p => p.Categories).First(c => c.CategoryID == categoryId)
许多其他变体。但是我没有让它工作。
在运行时我收到 InvalidCastException。Category.CategoryID 和 categoryId 都是 int。
创建一个 ICategoriesRepository 会更好吗?也许它也有性能优势?我显然是 LINQ 的新手,所以不确定如何正确地做事。
编辑(代码示例):
public interface IProductsRepository
{
IQueryable<Product> Products { get; }
}
public class ProductsController : Controller
{
public int PageSize = 4;
private IProductsRepository productsRepository;
public ProductsController(IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
public ViewResult ListById(int categoryId, int page = 1)
{
Category cat;
// What do I need here to get the Category with the categoryId regardless of which Product it is connected to?
return List(cat, page);
}
private ViewResult List(Category category, int page = 1) { //this code works }
}
[Table(Name = "products")]
public class Product
{
[HiddenInput(DisplayValue = false)]
[Column(Name = "id", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int ProductID { get; set; }
[Column]
public string Name { get; set; }
[Column(Name = "info")]
public string Description { get; set; }
public float LowestPrice
{
get { return (from product in ProductSubs select product.Price).Min(); }
}
private EntitySet<Category> _Categories = new EntitySet<Category>();
[System.Data.Linq.Mapping.Association(Storage = "_Categories", OtherKey = "CategoryID")]
public ICollection<Category> Categories
{
get { return _Categories; }
set { _Categories.Assign(value); }
}
}
[Table(Name = "products_types")]
public class Category
{
[HiddenInput(DisplayValue = false)]
[Column(Name = "id", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int CategoryID { get; set; }
[Column(Name = "id")] // Temp solution, real name is localized in a separate table
public string Name { get; set; }
private EntitySet<Product> _Products = new EntitySet<Product>();
[System.Data.Linq.Mapping.Association(Storage = "_Products", OtherKey = "ProductID")]
public ICollection<Product> Products
{
get { return _Products; }
set { _Products.Assign(value); }
}
}
编辑:
我尝试通过 ICategoriesRepository 来实现,但我得到了同样的错误。这是一个完整的堆栈跟踪:
[InvalidCastException: 指定的强制转换无效。] System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) + 1191 System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(表达式查询,QueryInfo[] queryInfos,IObjectReaderFactory 工厂,Object[] userArguments,ICompiledSubQuery[] subQueries)+118 System.Data.Linq.SqlClient.SqlProvider.System.Data。 Linq.Provider.IProvider.Execute(Expression query) +342 System.Data.Linq.Table 1.System.Linq.IQueryProvider.Execute(Expression expression) +58
System.Linq.Queryable.First(IQueryable
1 source, Expression 1 predicate) +287
MaxFPS.WebUI.Controllers.ProductsController.ListById(Int32 categoryId, Int32 page) in d:\Filer\Documents\Dropbox\ZkilfinG\webbutveckling\MaxFPS\VS Projects\MaxFPS\MaxFPS\Controllers\ProductsController.cs:26
lambda_method(Closure , ControllerBase , Object[] ) +140
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
2 参数) +182 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +27
System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
System.Web.Mvc.Async.<>c__DisplayClass8
1.b__7(IAsyncResult _) +10 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58
System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +225
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult
1.End() +50 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34 System.Web.Mvc.Async。 <>c__DisplayClass2a.b__20() +24 System.Web.Mvc.Async.<>c__DisplayClass25.b__22(IAsyncResult asyncResult) +99 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult
1.End() +55 System.Web.Mvc。 Controller.EndExecuteCore(IAsyncResult asyncResult) +39 System.Web.Mvc.Async.<>c__DisplayClass4.b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult1.End() +55
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult
1.End() +55 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult 结果) +9 System.Web.CallHandlerExecutionStep.System .Web.HttpApplication.IExecutionStep.Execute() +9629708 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
编辑:
当 categoryId 设置为不在数据库中的 id 时,我得到一个空序列。这对我来说表明比较代码是正确的,但我不明白无效转换的原因或内容。
[InvalidOperationException:序列不包含元素] System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +1191 System .Data.Linq.SqlClient.SqlProvider.ExecuteAll(表达式查询,QueryInfo[] queryInfos,IObjectReaderFactory factory,Object[] userArguments,ICompiledSubQuery[] subQueries)+118 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq。 Provider.IProvider.Execute(表达式查询)+342 System.Data.Linq.Table 1.System.Linq.IQueryProvider.Execute(Expression expression) +58
System.Linq.Queryable.First(IQueryable
1 源,表达式1 predicate) +287
MaxFPS.WebUI.Controllers.ProductsController.ListById(Int32 categoryId, Int32 page) in d:\Filer\Documents\Dropbox\ZkilfinG\webbutveckling\MaxFPS\VS Projects\MaxFPS\MaxFPS\Controllers\ProductsController.cs:28
lambda_method(Closure , ControllerBase , Object[] ) +140
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
2 参数)+182 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +27
System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
System.Web.Mvc.Async.<>c__DisplayClass8
1.b__7(IAsyncResult _) +10 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58
System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +225
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult
1.End() +50 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34 System.Web.Mvc.Async。 <>c__DisplayClass2a.b__20() +24 System.Web.Mvc.Async.<>c__DisplayClass25.b__22(IAsyncResult asyncResult) +99 System.Web.Mvc.Async.WrappedAsyncResult 1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult
1.End() +55 System.Web.Mvc。 Controller.EndExecuteCore(IAsyncResult asyncResult) +39 System.Web.Mvc.Async.<>c__DisplayClass4.b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult1.End() +55
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +29
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult
1.End() +55 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +31 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult 结果) +9 System.Web.CallHandlerExecutionStep.System .Web.HttpApplication.IExecutionStep.Execute() +9629708 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously