HI,
We have encounter some issue on objectMapper after we have upgraded to .Net Core 3.1. Is there any workaround / solution?
Message: variable 'TravellerList' of type 'System.Collections.Generic.IEnumerable`1[ThinknInsurTech.Quote.Quote_Policy_TravelTraveller]' referenced from scope '', but it is not defined
Error Stack:
at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection1 nodes, Func
2 elementVisitor)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection1 nodes) at System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression
1 node)
at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_01.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func
1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetEnumerator() at System.Collections.Generic.LargeArrayBuilder
1.AddRange(IEnumerable1 items) at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable
1 source)
at System.Linq.SystemCore_EnumerableDebugView`1.get_Items()
If we change "ObjectMapper.Map<List<QuotePolicyTravelTraveller>>(TravellerList.ToList())"
We got following error
Unable to cast object of type 'System.Linq.Expressions.TypedParameterExpression' to type 'Microsoft.EntityFrameworkCore.Query.ShapedQueryExpression'.
18 Answer(s)
-
0
private IQueryable<TravelExceptionListingOutput> TravelExceptionListingQuery(GetTravelExceptionListingInput input) { List<string> exceptionErrorCode = new List<string>() { "000", "003", "004", "008" }; var query = (from quotepolicy in _quotePolicyRepository.GetAll().Where(p => p.StatusId.Equals(2)) join quotepolicytravel in _quotePolicyTravelRepository.GetAll().Where(p => !exceptionErrorCode.Contains(p.ePolicyRespCode)) on quotepolicy.Id equals quotepolicytravel.QuotePolicyId join quotepolicypayment in _quotePolicyPaymentRepository.GetAll().Where(p => p.PaymentStatus == Convert.ToString((byte)PaymentStatus.Success)) on quotepolicy.Id equals quotepolicypayment.QuotePolicyId join quotepolicytraveltraveller in _quotePolicyTravelTravellerRepository.GetAll().Where(x => x.IsPolicyHolder == true) on quotepolicy.Id equals quotepolicytraveltraveller.QuotePolicyId into TravellerList from quotepolicytraveltraveller in TravellerList.DefaultIfEmpty() where ((input.ReferenceNo.IsNullOrWhiteSpace() || quotepolicy.ReferenceNo.Equals(input.ReferenceNo)) && ((input.PolicyStartDate.IsNullOrWhiteSpace() || (quotepolicy.CreationTime.Date >= DateTime.Parse(input.PolicyStartDate).Date && quotepolicy.CreationTime.Date <= DateTime.Parse(input.PolicyEndDate).Date) ))) select new TravelExceptionListingOutput { QuotePolicyId = quotepolicy.Id, QuotePolicy = ObjectMapper.Map<Dto.QuotePolicy>(quotepolicy), QuotePolicyTravel = ObjectMapper.Map<QuotePolicyTravel>(quotepolicytravel), QuotePolicyTravelTraveller = null, //ObjectMapper.Map<List<QuotePolicyTravelTraveller>>(TravellerList.ToList()), QuotePolicyPayment = ObjectMapper.Map<QuotePolicyPayment>(quotepolicypayment), ResponseCode = quotepolicytravel.ePolicyRespCode, ResponseMessage = quotepolicytravel.ePolicyIntMessage + " " + quotepolicytravel.ePolicyRespMessage }); return query; } ```
-
0
Hi @thinkn.tech,
I think this code is generated by AspNet Zero Power Tools. Latest version of Power Tools doesn't create such mapping anymore because of EF Core 3.1 breaking changes. You can create a test entity, see the newly generated code and modify your existing code accordingly.
-
0
Hi @ismcagdas,
We actually don't use AspNet Zero Power Tools to generate class but I just wonder,
Below linq statement will returning multiple records ... join quotepolicytraveltraveller in _quotePolicyTravelTravellerRepository.GetAll().Where(x => x.IsPolicyHolder == true) on quotepolicy.Id equals quotepolicytraveltraveller.QuotePolicyId into TravellerList from quotepolicytraveltraveller in TravellerList.DefaultIfEmpty() .... and from the results, we just map as following code
QuotePolicyTravelTraveller = ObjectMapper.Map<List<QuotePolicyTravelTraveller>>(TravellerList.ToList()),
QuotePolicyTravelTraveller entity public class QuotePolicyTravelTraveller : EntityDto<long> { public long QuotePolicyId { get; set; } [StringLength(100)] public string FullName { get; set; } [Required] public bool IsPolicyHolder { get; set; } [Required] [StringLength(20)] public string NRIC { get; set; } }
TravelExceptionListingOutput entity public class TravelExceptionListingOutput { public long QuotePolicyId { get; set; } public QuotePolicy QuotePolicy { get; set; } public QuotePolicyTravel QuotePolicyTravel { get; set; } public List<QuotePolicyTravelTraveller> QuotePolicyTravelTraveller { get; set; } public QuotePolicyPayment QuotePolicyPayment { get; set; } public string ResponseCode { get; set; } public string ResponseMessage { get; set; } }
is there any other possible solution that you can suggest?
-
0
Hi,
When I look at your query, I see several parts which can't be converted to SQL by EF Core.
- Convert.ToString
- DateTime.Parse
- ObjectMapper.Map in select statements
You can basically define variables for
Convert.ToString
andDateTime.Parse
before your LinQ query and use those fields. After that, you can remove ObjectMapper.Map statements in your LinQ select statement and do the mapping after retrieving the result of your query. So, your TravelExceptionListingQuery method shouldn't return an output class but it should return a class which contains Entity classes as parameters instead of DTOs. For example;select new MyTravelExceptionListing { QuotePolicyId = quotepolicy.Id, QuotePolicy = quotepolicy, QuotePolicyTravel = quotepolicytravel, QuotePolicyTravelTraveller = null, //ObjectMapper.Map<List<QuotePolicyTravelTraveller>>(TravellerList.ToList()), QuotePolicyPayment = quotepolicypayment, ResponseCode = quotepolicytravel.ePolicyRespCode, ResponseMessage = quotepolicytravel.ePolicyIntMessage + " " + quotepolicytravel.ePolicyRespMessage })
-
0
Hi,
Any update? I have rephrase a simple joining with One to Many relationship as below.
private IQueryable<TravelExceptionListingOutputTesting> TravelExceptionListingQueryTesting(GetTravelExceptionListingInput input) { var fristQuery = (from quotepolicy in _quotePolicyRepository.GetAll().Where(p => p.StatusId.Equals(2)) join quotepolicytraveltraveller in _quotePolicyTravelTravellerRepository.GetAll().Where(x => x.IsPolicyHolder == true) on quotepolicy.Id equals quotepolicytraveltraveller.QuotePolicyId into TravellerList from quotepolicytraveltraveller in TravellerList.DefaultIfEmpty() select new TravelExceptionListingOutputTesting { QuotePolicyId = quotepolicy.Id, QuotePolicy = quotepolicy, QuotePolicyTravelTraveller = quotepolicytraveltraveller, QuotePolicyTravelTravellerList = ObjectMapper.Map<List<Quote_Policy_TravelTraveller>>(TravellerList), }); return fristQuery; } public class TravelExceptionListingOutputTesting { public long QuotePolicyId { get; set; } public Quote_Policy QuotePolicy { get; set; } public Quote_Policy_TravelTraveller QuotePolicyTravelTraveller { get; set; } public List<Quote_Policy_TravelTraveller> QuotePolicyTravelTravellerList { get; set; } }
but i still received error as following:- variable 'TravellerList' of type 'System.Collections.Generic.IEnumerable`1[ThinknInsurTech.Quote.Quote_Policy_TravelTraveller]' referenced from scope '', but it is not defined Appreciate that you can provide me solution as we have a lot of method using this way and it hits only when we upgrading .Net Core 3.
-
0
Hi,
For your final query, you can't use
TravellerList
, you can only usequotepolicytraveltraveller
. You are making one join toQuote_Policy_TravelTraveller
table. Does your entityTravelExceptionListingOutputTesting
really has those two fields (QuotePolicyTravelTraveller and QuotePolicyTravelTravellerList) ? If so, what is the relation for QuotePolicyTravelTravellerList ? I can only see QuotePolicyId in your entity. -
0
Hi,
Of cours,e you can create One to Many relations. I was talking about the entity you have shared. Anyway, you can just use it like below;
QuotePolicyTravelTravellerList = TravellerList
instead of
QuotePolicyTravelTravellerList = ObjectMapper.Map<List<Quote_Policy_TravelTraveller>>(TravellerList)
Then, you have to map your result to your Dto. Mapping operation will map nested objects and lists in your result object to your Dto.
-
0
Hi,
I followed what you have recommended but still not successful.
if i do QuotePolicyTravelTravellerList = TravellerList
QuotePolicyTravelTravellerList need to be accept public List<Quote_Policy_TravelTraveller> QuotePolicyTravelTraveller { get; set; }
If i run query, it prompt me "Unable to cast object of type 'System.Linq.Expressions.TypedParameterExpression' to type 'Microsoft.EntityFrameworkCore.Query.ShapedQueryExpression'."
You can have a try. Or can show me some workable sample code which involved 1-M Relathipship
-
0
var fristQuery = (from quotepolicy in _quotePolicyRepository.GetAll().Where(p => p.StatusId.Equals(2)) join quotepolicytraveltraveller in _quotePolicyTravelTravellerRepository.GetAll().Where(x => x.IsPolicyHolder == true) on quotepolicy.Id equals quotepolicytraveltraveller.QuotePolicyId into TravellerList from quotepolicytraveltraveller in TravellerList.DefaultIfEmpty() select new TravelExceptionListingOutputTesting { QuotePolicyId = quotepolicy.Id, QuotePolicyTravelTraveller = TravellerList.ToList() });
public class TravelExceptionListingOutputTesting { public long QuotePolicyId { get; set; } public List<Quote_Policy_TravelTraveller> QuotePolicyTravelTraveller { get; set; } }
**1 item** of _quotePolicyRepository and **Many** records in _quotePolicyTravelTravellerRepository Very appreciate for your help.
-
0
Hi,
Your query is correct except using ToList
var fristQuery = (from quotepolicy in _quotePolicyRepository.GetAll().Where(p => p.StatusId.Equals(2)) join quotepolicytraveltraveller in _quotePolicyTravelTravellerRepository.GetAll().Where(x => x.IsPolicyHolder == true) on quotepolicy.Id equals quotepolicytraveltraveller.QuotePolicyId into TravellerList from quotepolicytraveltraveller in TravellerList.DefaultIfEmpty() select new TravelExceptionListingOutputTesting { QuotePolicyId = quotepolicy.Id, QuotePolicyTravelTraveller = TravellerList });
Then, you can map output of your query result to
TravelExceptionListingOutputTesting
. Does that work for you ?