Async lambda expressions cannot be converted to expression trees - c#

public static async Task<Bureau> getBubreauById(int? idBureau)
{
if (idBureau > 0)
{
using (var dbContext = new AppDbContext(optionsBuilder.Options))
{
return await dbContext.Bureaus.FirstOrDefaultAsync(x => x.id == idBureau);
}
}
return null;
}
And in the MapperInitializer
.ForMember(aud => aud.LibelleBureauEnlevement, o => o.MapFrom(async au => (await SmartTransitHelper.getBubreauById(au.bureau_dedouanement)).libelle)
Here I wanna Map the LibelleBureauEnlevement to the returned libelle value from SmartTransitHelper.getBubreauById(au.bureau_dedouanement)
but I have this error, I wanna know what is wrog, why it's not workin?

Related

Get lambda expression from where clause or IQueryable/IEnumerable

Is there a way to get the expression from known where clause, then pass it to other Where(<expression>) clause?
I'm on .NET Core 3.0 preview with EF Core preview.
Included linq and linq dynamic
public void myFunction ()
{
var expression = GetAllItems()
.Where(x => x.Id == 5 && x.Desc.Contains("foos"))
.AwesomeGetExpressioneMagicFunction();
var res = GenericBeforeSaveValidation(expression);
}
public IQueryable<T> GenericBeforeSaveValidation("delegate/expression" exp)
{
//some generic stuff before
return sourceItems.Where(exp);
}
Just save the lambda in a function variable and reuse it:
public void myFunction ()
{
Expression<Func<ItemType, bool>> expression = x => x.Id == 5 && x.Desc.Contains("foos");
var items = GetAllItems()
.Where(expression)
.ToList();
var res = GenericBeforeSaveValidation(expression);
}
public IQueryable<ItemType> GenericBeforeSaveValidation(Expression<Func<ItemType, bool>> exp)
{
//some generic stuff before
return sourceItems.Where(exp);
}
"itemType" is the actual type of your items.

Cannot access variable on mapping (C#)

I have a method on the back end, that gets values related to a foreign key of the table.
Those foreign keys can be nullable, but one of those keys always will have value.
Here is method
public async Task<ListResultDto<QuoteListDto>> GeQuotesTabData(int? landlordId, int? agentId,
int? propertyTenantId)
{
if (landlordId.HasValue)
{
var query = _quoteRepository.GetAll()
.Where(x => x.LandlordId == landlordId);
}
if (agentId.HasValue)
{
var query = _quoteRepository.GetAll()
.Where(x => x.AgentId == agentId);
}
if (propertyTenantId.HasValue)
{
var query = _quoteRepository.GetAll()
.Where(x => x.PropertyTenantId == propertyTenantId);
}
return new ListResultDto<QuoteListDto>(await query.ProjectTo<QuoteListDto>(ObjectMapper)
.OrderBy(x => x.Id).ToListAsync());
}
At this row, I get an error Cannot resolve symbol query
return new ListResultDto<QuoteListDto>(await query.ProjectTo<QuoteListDto>(ObjectMapper)
.OrderBy(x => x.Id).ToListAsync());
How do I need to rewrite my method?
Declare and initialise your variable. Additionally I would re-write you method like so:
public async Task<ListResultDto<QuoteListDto>> GeQuotesTabData(int? landlordId, int? agentId,
int? propertyTenantId)
{
var query = _quoteRepository.GetAll();
if (landlordId.HasValue)
{
query = query.Where(x => x.LandlordId == landlordId);
}
if (agentId.HasValue)
{
query = query.Where(x => x.AgentId == agentId);
}
if (propertyTenantId.HasValue)
{
query = query .Where(x => x.PropertyTenantId == propertyTenantId);
}
return new ListResultDto<QuoteListDto>(await query.ProjectTo<QuoteListDto>(ObjectMapper)
.OrderBy(x => x.Id).ToListAsync());
}
Also taken from this answer, you can create a WhereIf extension to clean up the if statements.
public static IQueryable<TSource> WhereIf<TSource>(
this IQueryable<TSource> source,
bool condition,
Expression<Func<TSource, bool>> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
Making your code look like this:
public async Task<ListResultDto<QuoteListDto>> GeQuotesTabData(int? landlordId, int? agentId,
int? propertyTenantId)
{
var list = await _quoteRepository.GetAll()
.WhereIf(landlordId.HasValue, x => x.LandlordId == landlordId)
.WhereIf(agentId.HasValue, x => x.AgentId == agentId)
.WhereIf(propertyTenantId.HasValue, x => x.PropertyTenantId == propertyTenantId)
.ProjectTo<QuoteListDto>(ObjectMapper)
.OrderBy(x => x.Id)
.ToListAsync();
return new ListResultDto<QuoteListDto>(list);
}
Your problem is variable scope. When you define a variable it is only visible in the scope you define it in.
You define three different query variables in a local scope. None of them are accessible where you try to use it.
You need to define it before using it, something like this:
public async Task<ListResultDto<QuoteListDto>> GeQuotesTabData(int? landlordId, int? agentId,
int? propertyTenantId)
{
IQueryable<Quote> query = null;
if (landlordId.HasValue)
{
query = _quoteRepository.GetAll().Where(x => x.LandlordId == landlordId);
}
if (agentId.HasValue)
{
query = _quoteRepository.GetAll().Where(x => x.AgentId == agentId);
}
if (propertyTenantId.HasValue)
{
query = _quoteRepository.GetAll().Where(x => x.PropertyTenantId == propertyTenantId);
}
return new ListResultDto<QuoteListDto>(await query.ProjectTo<QuoteListDto>(ObjectMapper)
.OrderBy(x => x.Id).ToListAsync());
}
Of course all of your queries should be of the same type. Otherwise you will have to define and execute them in the local scopes.
You should probably also add some error handling of the case where query is null, when you try to use it.

DocumentClient CreateDocumentQuery async

Why is there no async version of CreateDocumentQuery?
This method for example could have been async:
using (var client = new DocumentClient(new Uri(endpointUrl), authorizationKey, _connectionPolicy))
{
List<Property> propertiesOfUser =
client.CreateDocumentQuery<Property>(_collectionLink)
.Where(p => p.OwnerId == userGuid)
.ToList();
return propertiesOfUser;
}
Good query,
Just try below code to have it in async fashion.
DocumentQueryable.CreateDocumentQuery method creates a query for documents under a collection.
// Query asychronously.
using (var client = new DocumentClient(new Uri(endpointUrl), authorizationKey, _connectionPolicy))
{
var propertiesOfUser =
client.CreateDocumentQuery<Property>(_collectionLink)
.Where(p => p.OwnerId == userGuid)
.AsDocumentQuery(); // Replaced with ToList()
while (propertiesOfUser.HasMoreResults)
{
foreach(Property p in await propertiesOfUser.ExecuteNextAsync<Property>())
{
// Iterate through Property to have List or any other operations
}
}
}
Based on Kasam Shaikh's answer I've created ToListAsync extensions
public static async Task<List<T>> ToListAsync<T>(this IDocumentQuery<T> queryable)
{
var list = new List<T>();
while (queryable.HasMoreResults)
{ //Note that ExecuteNextAsync can return many records in each call
var response = await queryable.ExecuteNextAsync<T>();
list.AddRange(response);
}
return list;
}
public static async Task<List<T>> ToListAsync<T>(this IQueryable<T> query)
{
return await query.AsDocumentQuery().ToListAsync();
}
You can use it
var propertiesOfUser = await
client.CreateDocumentQuery<Property>(_collectionLink)
.Where(p => p.OwnerId == userGuid)
.ToListAsync()
Note that request to have CreateDocumentQuery async is open on github

c# mongo FindOne slow

Sometimes, a FindOne takes more than a second => "_keywordRepo.GetKeyword 1034 ms". Here is an exemple for production code.
Here is the code from the DAL : KeywordRepository :
public async Task<Keyword> GetKeyword(string keywordName)
{
return await MongoClientWrapper.FindOne<Keyword>(k => k.KeywordName == keywordName).ConfigureAwait(false);
}
MongoClientWrapper :
public static async Task<T> FindOne<T>(Expression<Func<T, bool>> memberExpression, FindOptions<T> findOptions = null)
{
var coll = GetCollection<T>();
if (findOptions == null)
findOptions = new FindOptions<T>();
findOptions.Limit = 1;
IAsyncCursor<T> task = await coll.FindAsync(memberExpression, findOptions).ConfigureAwait(false);
return await task.FirstOrDefaultAsync().ConfigureAwait(false);
}
There is indeed an index on "KeywordName" in mongo.
Is there something wrong ?

QueryOver where generator Nhibernate

Hello i got some method that generating where statment programmatically how can i move where generation to other class method anyone can help ?
public static List<MME.Objects.TypedLists.InvoiceList> GetList(List<MMPFramework.SearchParameter> parameter)
{
MME.Objects.Invoice Invoice = null;
MME.Objects.Contractor Contractor = null;
MME.Objects.Contract Contract = null;
MME.Objects.TypedLists.InvoiceList invoiceList= null;
var t = MME.DAL.NhSessionHelper.GetCurrentSession().QueryOver<MME.Objects.Invoice>(() => Invoice);
foreach (var searchParameter in parameter)
{
if(searchParameter.Expression == "Like")
{
t.Where(Restrictions.Like(searchParameter.PropertyName, searchParameter.ObjectValueLo));
}
else if (searchParameter.Expression == "Eq")
{
t.Where(Restrictions.Eq(searchParameter.PropertyName, searchParameter.ObjectValueLo));
}
else if (searchParameter.Expression == "Between")
{
t.Where(Restrictions.Between(searchParameter.PropertyName, searchParameter.ObjectValueLo,searchParameter.ObjectValueHi));
}
else if(searchParameter.Expression == "Gt")
{
t.Where(Restrictions.Gt(searchParameter.PropertyName, searchParameter.ObjectValueLo));
}
else if (searchParameter.Expression == "Lt")
{
t.Where(Restrictions.Lt(searchParameter.PropertyName, searchParameter.ObjectValueLo));
}
else
{
//todo more
}
//t.Where(Restrictions.Eq(searchParameter.PropertyName, searchParameter.ObjectValue));
}
t.JoinQueryOver(() => Invoice.Contractor, () => Contractor, JoinType.LeftOuterJoin)
.JoinQueryOver(() => Invoice.Contract, () => Contract, JoinType.LeftOuterJoin)
.Select(Projections.Property(() => Invoice.Id).WithAlias(() => invoiceList.Id),
Projections.Property(() => Invoice.Number).WithAlias(() => invoiceList.InvoiceNumber),
Projections.Property(() => Contractor.Name).WithAlias(() => invoiceList.ContractorName),
Projections.Property(() => Contract.Number).WithAlias(() => invoiceList.ContractNumber)
)
.TransformUsing(Transformers.AliasToBean<MME.Objects.TypedLists.InvoiceList>());
return t.List<MME.Objects.TypedLists.InvoiceList>().ToList();
}
I've tried with this but it seems to not work.... Hope someone was doing something and can help me to handle with it.
public class BaseList
{
public object WhereGenerator(object ob)
{
QueryOver Ded = ob as QueryOver;
return null;
}
}
foreach (var restriction in BaseList.Createrestrictions(parameter))
{
t.Where(restriction);
}
public class BaseList
{
public IEnumerable<AbstractCriterion> Createrestrictions(List<MMPFramework.SearchParameter> parameter)
{
return parameter.Select(ToCritieria);
}
private AbstractCriterion ToCritieria(SearchParameter searchParameter)
{
if(searchParameter.Expression == "Like")
{
return Restrictions.Like(searchParameter.PropertyName, searchParameter.ObjectValueLo);
}
else ...
}
}

Categories

Resources