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
hi
Can you share the full code?
-
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,
Your suggestion work half if not list. What if we have One to Many relationship (i.e. 1 Quotation have many traveller on board). How i can do the bind to my DTO if is List<QuotePolicyTravelTraveller>?
-
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,
Is that mean in .Net Core 3.1. We cannot have One to Many?
1 Quote_Policy has many Quote_Policy_TravelTraveller (1 : M)
How i can retrieve all Quote_Policy_TravelTraveller that associate to Quote_Policy? If cannot, how i can achieve this requirement?
Appreaciate and Thank.
-
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
Hi,
Could you share your entire query ? By the way, this is not related to AspNet Zero but we will try to help you if we can.
-
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 ? -
0
-
0
Hi,
Is it possible to share youır project via email with [email protected] ? We can run your project and fix the query for you.
Thanks,
-
0
HI,
I have shared my project. Please check your email.
Many thank and appreciate.
-
0
Hi,
Thanks, we got the email and we will reply to you via email.
Thanks,