AutoMapper - Using ProjectTo method - c#

I am using AutoMapper in my code and I wanna use ProjectTo for the mappings like this:
var queryable = await _unitOfWork.ProductRepository
.GetList(query);
return new Paging<ProductListDto>
{
Data = queryable.Data.ProjectTo<ProductListDto>(_mapper.ConfigurationProvider).ToList()
};
but I got the following error while using ProjectTo:

ProjectTo method only supports IQueryable but not IEnumerable.
You should use the basic _mapper.Map<T>(/* source */).
return new Paging<ProductListDto>
{
Data = _mapper.Map<List<ProductListDto>>(queryable.Data)
};

Related

The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'

I'm trying to mock some DB access code using simple lists. It generally works except for Async. which causes the error saying the provider does not support Iqueriable. I tries a few suggested solutions but they seem to cause an expression error when executing the linq query
[Fact]
public async Task TestAsyncFromList()
{
List<int> items = new List<int>() { 1,2,3,4,5,6,7,8,9,10};
var queryable = items.AsQueryable();
var totalSync = queryable.Count();
var totalAsync = await queryable.CountAsync(); // The provider for the source 'IQueryable' doesn't implement 'IAsyncQueryProvider'
Assert.True(totalSync==totalAsync);
}
I was expecting that there is an 'AsAsyncQueiable' solution
Tried this The provider for the source IQueryable doesn't implement IAsyncQueryProvider - but got Expression error

Using extension method in Linq to Entities

Code:
public static IEnumerable<TableRowModel> GetRows()
{
var to_ret = db.TableRows.select(x=> new TableRowModel(){
TableRowId = x.TableRowId,
Type = x.Type,
Name = x.Name,
CreatedAt = x.CreatedAt,
ModifiedAt = x.ModifiedAt,
Enums = x.Enums.Select(y => y.ToEnumModel()),
});
return to_ret;
}
public static EnumModel ToEnumModel(this Enum x)
{
var to_ret = new EnumModel()
{
CFPId = x.CFPId,
CreatedAt = x.CreatedAt,
ModifiedAt = x.ModifiedAt,
};
return to_ret;
}
I get the following error when using the GetRows method:
LINQ to Entities does not recognize the method
Given the error, it's understood that LINQ To Entities is not able to recognize the extension method ToEnumModel.
I would like to know if there is a way around this?
So that I would not be repeating ToEnumModel code again in GetRows extension.
Under normal circumstances, when performing an operation like a Where in EntityFramework, it isn't actually executed in memory like when you operate on an enumerable (like a List). Instead, it converted into SQL which is then executed by the Db provider. This means that doing certain things, such as using extension methods on objects, is not an option, as the converter cannot turn such things into SQL.
The quickest and easiest solution would be to load your set in-memory, where it can be operated on like any other enumerable. You can do this like so:
var result = myDbSet.AsEnumerable().Etc()
Etc() here represents all other operations you want to run. Be advised however, that this will load all data into memory, which may be prohibitively slow and expensive in some scenarios. One way to alleviate this is to put AsEnumerable() right before you need to use the extension method, thus offloading as many operations as possible to the provider. For example this:
var result = myDbSet.Where([condition]).AsEnumerable().Select(item => item.ExtensionMethod());
Might be much quicker and lighter than this:
var result = myDbSet.AsEnumerable().Where([condition]).Select(item => item.ExtensionMethod());
Your ability to use extension methods in EF is limited, but you can still extend your IQueryables
public static class Extensions
{
public static IQueryable<MyModelVM> SelectVMs(this IQueryable<MyModel> models)
{
return models.Select(x => new MyModelVM { MyModelId = x.MyModelId });
}
}

C# mongodb driver 2.0, how to make ToListAsync() to return List<Entity>?

I am trying to using the mongodb new c# driver, which is version 2.x.
I want to retrieve all the Entity object as a List<Entity>, however, ToListAsync seems only return List<BsonDocument>,
var collection = _db.GetCollection<Entity>("EntityTable");
var ret = await collection.Find("{}").Project(Builders<Enity>.Projection.Exclude("_id")).ToListAsync();
How can I get List<Entity>?
Just use the As<TResult>() method (it's a part of the MongoDB.Driver.IFindFluent<TDocument, TProjection> interface).
Here's your code, updated to use this method:
var ret = await collection
.Find("{}")
.Project(Builders<Entity>.Projection.Exclude("_id"))
.As<Entity>()
.ToListAsync();
You might need to add the [BsonIgnoreExtraElements] attribute to your Entity class in order to make this work.
Yes #Donut, you can use like this too
var ret = await collection
.Find("{}")
.Project<Entity>(Builders<Entity>.Projection.Exclude("_id"))
.ToListAsync();

Creating JSON object from Ienumerable using LINQ

I am trying to use LINQ to JSON to create a JSON object using the http://james.newtonking.com/json (JSON.NET) framework.
Basically I am trying to create a certain structure from the IEnumerable output. Have something like Products-> Actual,forecast,Target.
The LINQ to XML statement works fine and I can see the result. Is it due to deferred execution and lazy evaluation in LINQ to XML? If yes, how do I solve it.
This is what my LINQ to XML method looks like
IEnumerable resultSet = (xmlDoc.Root.Descendants(ns + "Row").Select(result => new
{
MonthYearShortName = (DateTime)result.Element(ns + "Column0"),
Product = (String)result.Element(ns + "Column1"),
Actual = (decimal)result.Element(ns + "Column2"),
Forecast = (decimal)result.Element(ns+"Column3"),
Target = (decimal)result.Element(ns + "Column4"),
}));
And this is my LINQ to JSON. The example I am using comes from http://james.newtonking.com/json/help/index.html?topic=html/CreatingLINQtoJSON.htm
JObject rss =
resultSet.Select(p => new JObject(p.Product,
new JProperty("MonthYearShortName", p.MonthYearShortName),
new JProperty("Actual", p.Actual),
new JProperty("Forecast", p.Forecast),
new JProperty("Target", p.Target)));
Console.WriteLine(rss.ToString());
When I execute the LINQ to JSON statements I get the below error message
Error 5 'System.Collections.IEnumerable' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.IEnumerable' could be found
My usings
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Extensions = System.Xml.Linq.Extensions;
Not really sure why I am unable to do a select in the second LINQ to JSON statement.
Any help would be great.
Thanks!
The Select extension method is defined on the generic IEnumerable<T> interface (not the non-generic IEnumerable).
For the code to compile, you will need to first call Cast<>()
JObject rss =
resultSet.Cast<XElement>().Select(p => new JObject(p.Product,
new JProperty("MonthYearShortName", p.MonthYearShortName),
new JProperty("Actual", p.Actual),
new JProperty("Forecast", p.Forecast),
new JProperty("Target", p.Target)));
Console.WriteLine(rss.ToString());
(or convert to a generic IEnumerable<resultSet> in some other way)
This code should work if you are trying to get the JSON string:
var resultSet = (xmlDoc.Root.Descendants("Row").Select(result => new
{
MonthYearShortName = (DateTime)result.Element(ns + "Column0"),
Product = (String)result.Element("Column1"),
Actual = (decimal)result.Element("Column2"),
Forecast = (decimal)result.Element("Column3"),
Target = (decimal)result.Element("Column4"),
}));
var json = JsonConvert.SerializeObject(resultSet);
Console.WriteLine(json);

Linq To SQL Method with .Contains fails

I have the below Linq To SQL Method. When I step through the code spcCodeIDs contains the seven entries I am expecting. However I get a run-time exception of
Method 'Boolean Contains(System.String)' has no supported translation to SQL.
What am I missing?
public static DataTable GetSPCCodeList()
{
using (var context = ProviderDataContext.Create())
{
IQueryable<tblProviderAdminSPCCode> tSPCCode = context.GetTable<tblProviderAdminSPCCode>();
IList<string> spcCodeIDs = BLLCmo.FCApprovedSPCsForGreenSheet();
return (tSPCCode
.Where(spcCode => spcCode.Inactive == null && spcCodeIDs.Contains(spcCode.SPCCodeID))
.OrderBy(spcCode => spcCode.SPCCodeID)
.Select(spcCode => new { spcCode.SPCCodeID, spcCode.SPCDescription, spcCode.SPCCategoryID }))
.CopyLinqToDataTable();
}
}
LINQ to SQL can only support Contains translations form a concrete list and not the IList interface.. try changing your line from
IList<string> spcCodeIDs = BLLCmo.FCApprovedSPCsForGreenSheet();
to
List<string> spcCodeIDs = BLLCmo.FCApprovedSPCsForGreenSheet().ToList();
You need to pass a string as a parameter to Contains. So trying passing spcCode.SPCCodeID.ToString()

Categories

Resources