1

我有一个与此问题类似的问题: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(IQueryable1 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, IDictionary2 参数) +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__DisplayClass81.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.WrappedAsyncResult1.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.WrappedAsyncResult1.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.WrappedAsyncResult1.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(IQueryable1 源,表达式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, IDictionary2 参数)+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__DisplayClass81.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.WrappedAsyncResult1.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.WrappedAsyncResult1.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.WrappedAsyncResult1.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

4

1 回答 1

0

一旦我弄清楚了,这个错误就很简单了。在我的真实数据库中,我有一个 LocalizedCategory 来获取本地化的类别名称。在实施时,我想我可以跳过使用它来简化事情。所以我用这段代码给 Name 一个值:

    [Column(Name = "id")]
    public string Name { get; set; }

但是,由于数据库中的 id 是 int ,所以我遇到了异常。我现在将尝试立即使其与 LocalizedCategory 一起使用,尽管我遇到了另一个问题:为什么我会根据我对它的 LINQ 方式从我的 EntitySet 中获得不同的值?

于 2012-09-24T13:33:39.140 回答