I'm trying to build Category part for my application back-end. In Index action ill list Categories and its sub categories.
Here is my Category entity
public class Category : Entity<int>
{
public virtual int? ParentId { get; set; }
public virtual string Title { get; set; }
public virtual string Description { get; set; }
public virtual string MetaDescription { get; set; }
public virtual string MetaKeys { get; set; }
public virtual int Order { get; set; }
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> SubCategories { get; set; }
public virtual ContentState ContentState { get; set; }
}
public enum ContentState
{
Published = 1,
UnPublished = 0,
Featured = 2,
Trashed = -1
}
I created Dtos like below
public class GetAllCategorySummariesInput : IInputDto
{
public ContentState? ContentState { get; set; }
}
public class GetAllCategorySummariesOutput : IOutputDto
{
public List<CategorySummaryDto> AllCategorySummaries { get; set; }
}
[AutoMap(typeof(Category))]
public class CategorySummaryDto : EntityDto
{
public string Title { get; set; }
public int Order { get; set; }
public List<CategorySummaryDto> SubCategories { get; set; }
}
in service class im using this code
public GetAllCategorySummariesOutput GetAllCategorySummaries(GetAllCategorySummariesInput input)
{
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).OrderBy(x => x.Id).ToList();
return new GetAllCategorySummariesOutput
{
AllCategorySummaries = catList.MapTo<List<CategorySummaryDto>>()
};
}
This one is seems works fine. But, i only want Id, Title, Order and SubCategories
so i tried something like this:
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).Select(x => new { x.Id, x.Title, x.SubCategories, x.Order }).OrderBy(x => x.Id).ToList();
But im getting "Missing type map configuration or unsupported mapping." error at runtime detailed below
Missing type map configuration or unsupported mapping.\r\n\r\nMapping types:\r\n<>f__AnonymousType0
4 -> CategorySummaryDto\r\n<>f__AnonymousType0
4[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.ICollection1[[YouScene.Categories.Category, YouScene.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] -> YouScene.Categories.Dtos.CategorySummaryDto\r\n\r\nDestination path:\r\nList
1[0]\r\n\r\nSource value:\r\n{ Id = 2, Title = Michael Fassbender, SubCategories = System.Collections.Generic.HashSet`1[YouScene.Categories.Category], Order = 0 }"}
Well, i said "if door is not open for me, ill look for another one. "
Here.
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).Select(x => new CategorySummaryDto { Id = x.Id, Title = x.Title, SubCategories = x.SubCategories, Order = x.Order }).OrderBy(x => x.Id).ToList();
when i change the code like above 'SubCategories = x.SubCategories' shows error
Cannot implicitly convert type 'System.Collections.Generic.ICollection<YouScene.Categories.Category>' to 'System.Collections.Generic.List<YouScene.Categories.Dtos.CategorySummaryDto>'. An explicit conversion exists (are you missing a cast?)
She is right. Category is not CategorySummaryDto.
So i changed the code like below followed by a final hope
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).Select(x => new CategorySummaryDto { Id = x.Id, Title = x.Title, SubCategories = x.SubCategories.MapTo<List<CategorySummaryDto>>(), Order = x.Order }).OrderBy(x => x.Id).ToList();
in design time everything was seems good.
But when i run the code she throwed an error again.
Additional information: LINQ to Entities does not recognize the method 'System.Collections.Generic.List
1[YouScene.Categories.Dtos.CategorySummaryDto] MapTo[List
1](System.Object)' method, and this method cannot be translated into a store expression.
3 Answer(s)
-
0
This is completely out of scope of ABP, and related to automapper and LINQ, but I will try to help you if I can.
- See this code:
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).Select(x => new { x.Id, x.Title, x.SubCategories, x.Order }).OrderBy(x => x.Id).ToList();
catList is a List of an anonymous type! Since anonymous types are dynamic, you can not define a mapping (like [AutoMap(typeof(Category))]). So, you can use AutoMapper's dynamic mapping. It should be something like that, but search on web:
return new GetAllCategorySummariesOutput { AllCategorySummaries = Mapper.DynamicMap<List<CategorySummaryDto>>(catList) };
- Alternatively, you tried:
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).Select(x => new CategorySummaryDto { Id = x.Id, Title = x.Title, SubCategories = x.SubCategories.MapTo<List<CategorySummaryDto>>(), Order = x.Order }).OrderBy(x => x.Id).ToList();
This can not work since LINQ does not supports it. I don't know why :)
Eventually, your working case is good for me. But if you want, you can use DynamicMap of AutoMapper.
-
0
<cite>hikalkan: </cite>
- See this code:
var catList = _categoryRepository.GetAll().Where(x => x.ContentState == input.ContentState).Select(x => new { x.Id, x.Title, x.SubCategories, x.Order }).OrderBy(x => x.Id).ToList();
catList is a List of an anonymous type! Since anonymous types are dynamic, you can not define a mapping (like [AutoMap(typeof(Category))]). So, you can use AutoMapper's dynamic mapping. It should be something like that, but search on web:
return new GetAllCategorySummariesOutput { AllCategorySummaries = Mapper.DynamicMap<List<CategorySummaryDto>>(catList) };
That dynamic things worked fine. But!
Sql Server Profiler reported that query when _categoryRepository run.
SELECT [Project1].[Id] AS [Id], [Project1].[Title] AS [Title], [Project1].[Order] AS [Order], [Project1].[ContentState] AS [ContentState], [Project1].[C1] AS [C1], [Project1].[Id1] AS [Id1], [Project1].[ParentId] AS [ParentId], [Project1].[Title1] AS [Title1], [Project1].[Description] AS [Description], [Project1].[MetaDescription] AS [MetaDescription], [Project1].[MetaKeys] AS [MetaKeys], [Project1].[Order1] AS [Order1], [Project1].[ContentState1] AS [ContentState1] FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[Title] AS [Title], [Extent1].[Order] AS [Order], [Extent1].[ContentState] AS [ContentState], [Extent2].[Id] AS [Id1], [Extent2].[ParentId] AS [ParentId], [Extent2].[Title] AS [Title1], [Extent2].[Description] AS [Description], [Extent2].[MetaDescription] AS [MetaDescription], [Extent2].[MetaKeys] AS [MetaKeys], [Extent2].[Order] AS [Order1], [Extent2].[ContentState] AS [ContentState1], CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] FROM [dbo].[Category] AS [Extent1] LEFT OUTER JOIN [dbo].[Category] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ParentId] ) AS [Project1] ORDER BY [Project1].[Id] ASC, [Project1].[C1] ASC exec sp_executesql N'SELECT [Extent1].[Id] AS [Id], [Extent1].[ParentId] AS [ParentId], [Extent1].[Title] AS [Title], [Extent1].[Description] AS [Description], [Extent1].[MetaDescription] AS [MetaDescription], [Extent1].[MetaKeys] AS [MetaKeys], [Extent1].[Order] AS [Order], [Extent1].[ContentState] AS [ContentState] FROM [dbo].[Category] AS [Extent1] WHERE [Extent1].[ParentId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=9
As you can see all fields selected. I put breakpoint after the _categoryRepository, only selected fields returned, not all of them. I need some research about this i gues.
Thank you this tip.
<cite>hikalkan: </cite>
Eventually, your working case is good for me.
I need more samples. About ViewModels, Dtos.
İddiayı tutturayım alıcam zeroyu görmem lazım senin kodları. :) Teşekkürler yardımların için.
-
0
:D