使用LINQ查询嵌套集合时出现InvalidCastException

时间:2012-09-18 19:10:32

标签: c# linq-to-sql

我遇到与此问题类似的问题:linq question: querying nested collections

我有一个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(Expression query,QueryInfo [] queryInfos,IObjectReaderFactory factory,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个来源,表达式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,IDictionary 2 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。&lt;&gt; c__DisplayClass2a.b__20()+24    System.Web.Mvc.Async。&lt;&gt; 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。&lt;&gt; c__DisplayClass4.b__3(IAsyncResult ar)+23    System.Web.Mvc.Async.WrappedAsyncResult 1.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 result)+9    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+9629708    System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155

编辑:

当categoryId设置为不在数据库中的id时,我得到一个空序列。这对我来说表明比较代码是正确的,但我不明白为什么或无效的演员是什么。

[InvalidOperationException:Sequence不包含任何元素]    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(Expression query,QueryInfo [] queryInfos,IObjectReaderFactory factory,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个来源,表达式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,IDictionary 2 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。&lt;&gt; c__DisplayClass2a.b__20()+24    System.Web.Mvc.Async。&lt;&gt; 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。&lt;&gt; c__DisplayClass4.b__3(IAsyncResult ar)+23    System.Web.Mvc.Async.WrappedAsyncResult 1.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 result)+9    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+9629708    System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously

1 个答案:

答案 0 :(得分:0)

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

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

但是,由于数据库中的id是int,我得到了一个异常。我现在要尝试让它立即使用LocalizedCategory,尽管我还有另一个问题:Why do I get different values from my EntitySet depending on how I LINQ to it?

相关问题