We are getting some exception, Exception message: "The LINQ expression 'DbSet<FactInspection>() - .net-core

While update the .netcore 2.2 to 3.1, I am facing the issue.
.Where(f => f.Media_Id == __filter_MediaId_0 && f.Targeted_Date != null && f.Targeted_Date.Value.Date >= __filter_StartDate_Value_Date_1 && f.Targeted_Date.Value.Date <= __filter_EndDate_Value_Date_2)
.GroupBy(
keySelector: f => new {
Targeted_Year = f.Targeted_Year,
Targeted_Quarter = f.Targeted_Quarter,
Targeted_Quater_Range = f.Targeted_Quater_Range,
Phase = f.Phase == \"Completed\" ? \"Completed\" : \"Not >Completed\"
},
elementSelector: f => f)
.Select(e => new TargetDashboardResponse{
Targeted_Year = (Nullable<int>)e.Key.Targeted_Year.Value,
Quarter = e.Key.Targeted_Quarter,
Name = string.Format(
format: \"{0} ({1})\",
arg0: e.Key.Targeted_Quater_Range,
arg1: (object)e.Key.Targeted_Year),
Phase = e.Key.Phase,
Count = e
.Count()
}
)
.OrderBy(e0 => e0.Targeted_Year)'
could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.", Inner exception: "" , Stacktrace: " at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.g__CheckTranslated|15_0(ShapedQueryExpression translated, <>c__DisplayClass15_0& )

Exception message clearly says to add a call to one of these methods: ' AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync' at the end of your query.
For example: await (your query).ToListAsync()

Related

Core EF Outer Join,Count & Group

I'm trying to convert this SQL Query into Core EF:
SELECT w.IdShippingBatch, w.BookingNumber, COUNT(c.IdShippingOrder) AS ShippingOrders, w.CreatedOn, w.ModifiedOn
FROM dbo.Shipping`enter code here`Batch AS w LEFT OUTER JOIN
dbo.ShippingOrders AS c ON w.IdShippingBatch = c.IdShippingBatch
WHERE (w.IdCompany = 2) AND (w.IdDealer = 1)
GROUP BY w.IdShippingBatch, w.BookingNumber, w.CreatedOn, w.ModifiedOn
I have tried multiple solutions, including several here. My latest attempt looks like:
var data = (from w in _context.ShippingBatch
join c in _context.ShippingOrders on w.IdShippingBatch equals c.IdShippingBatch into t1
where w.IdCompany == idCompany && w.IdDealer == idDealer
from t2 in t1.DefaultIfEmpty()
group t2 by new { w.IdShippingBatch, w.BookingNumber, w.CreatedOn, w.ModifiedOn } into t3
select new ShippingBatchDTO
{
IdShippingBatch = t3.Key.IdShippingBatch,
BookingNumber = t3.Key.BookingNumber,
ShippingOrders = t3.Count(),
CreatedOn = t3.Key.CreatedOn,
ModifiedOn = t3.Key.ModifiedOn
});
I have also tried adding t3.count(m => m.something != null), but that throws an error.
One major point of EF is to map the relationship between entities so that you can leverage LINQ and let EF compose an SQL query rather than trying to replace SQL with LINQ-QL.
If your ShippingBatch is mapped with a collection of ShippingOrders...
var batches = _context.ShippingBatch
.Where(x => x.IdCompany == idCompany && x.IdDealer == idDealer)
.Select(x => new ShippingBatchDTO
{
IdShippingBatch = x.IdShippingBatch,
BookingNumber = x.BookingNumber,
ShippingOrders = x.ShippingOrders.Count(),
CreatedOn = x.CreatedOn,
ModifiedOn = x.ModifiedOn
}).ToList();
If your ShippingBatch does not have a collection of ShippingOrders, but your ShippingOrder reference an optional ShippingBatch.
var batches = _context.ShippingOrder
.Where(x => x.ShippingBatch != null
&& x.ShippingBatch.IdCompany == idCompany
&& x.ShippingBatch.IdDealer == idDealer)
.GroupBy(x => x.ShippingBatch)
.Select(x => new ShippingBatchDTO
{
IdShippingBatch = x.Key.IdShippingBatch,
BookingNumber = x.Key.BookingNumber,
ShippingOrders = x.Count(),
CreatedOn = x.Key.CreatedOn,
ModifiedOn = x.Key.ModifiedOn
}).ToList();
That should hopefully get you moving in the right direction. If not, expand your question to include details of what you are seeing, and what you expect to see along with definitions for the applicable entities.

Trying to get Distinct() and/or GroupBy(...) in returned ToList

The code is working and returning a good list with (6) items.
However, we are seeing duplicates productSKU. We want to do a
DISTINCt productSKU.
pM = (from oo in ctx.option1
where mArray.Contains(oo.option1Code)
select oo)
.Select(o => new ProductMatch
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}).ToList();
I have tried to add Distinct() after the Lambda but I still get (6) items.
I am also getting error when I add GroupBy(...) "Cannot convert lambda expression to type 'string' because it is not a delegate type"
Try this syntax:
pM = (from o in ctx.option1
where mArray.Contains(o.option1Code)
let t = new
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}
group o by t into grp
select new ProductMatch
{
productSKU = grp.Key.option1Code,
productPrice = grp.Key.price,
option1Desc = grp.Key.option1Desc
}).ToList();
When you use a Distinct on a lamba expression, the Distinct only looks at the EntityKey for the distinct comparision. You will need to implement your own IEqualityComparer for your select.
internal class UniqueProductComparer : IEqualityComparer<ProductMatch>
{
public bool Equals(ProductMatch x, ProductMatch y)
{
if(Object.ReferenceEquals(x,y)) return true;
if(Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y,null))
return false;
return x.productSKU == y.ProductSKU && x.productPrice == y.productPrice && x.option1Desc == y.option1Desc;
}
public int GetHashCode(ProductMatch match)
{
if (Object.ReferenceEquals(match,null)) return 0;
return match.productSKU.GetHashChode() + match.productPrice.GetHashCode() + match.option1Desc.GetHashCode();
}
}
Then in your lamba, change it to this:
pM = (from oo in ctx.option1
where mArray.Contains(oo.option1Code)
select oo)
.Select(o => new ProductMatch
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}).Distinct(new UniqueProductComparer()).ToList();
A slight variation of IAbstractDownvoteFactor's answer
pM = (from oo in ctx.option1
where mArray.Contains(oo.option1Code)
select oo)
.GroupBy(o => o.option1Code)
.Select(g => g.First())
.Select(o => new ProductMatch
{
productSKU = o.option1Code,
productPrice = o.price,
option1Desc = o.option1Desc
}).ToList();
Alternatively, if you use linq heavily and are open to using libraries, there is morelinq that gives you DistinctBy() extension and several other useful extensions.

Entity Framework query syntax

I having a trouble with a query
I need to take out the SHIPMENT from GetAllOrderData - the same place where you can find POD_DATE and RECEIVE_NAME...but I get an error
Error 1 The name 'x' does not exist in the current context
My code is:
public IEnumerable<ReportItemDTO> GetTaskProgress(DateTime targetDate)
{
try
{
var startDate = targetDate.Date;
var endDate = startDate.AddDays(1);
OrderDataRepository rep = new OrderDataRepository();
var query = rep.GetAllOrderData()
.Where(x => x.POD_DATE >= startDate && x.POD_DATE <= endDate)
.GroupBy(o => o.User)
.Select(g => new ReportItemDTO
{
DriverId = g.Key.Id,
PdriverName = g.Key.Name,
OrderCount = g.Count(),
ReportedOrdersCount = g.Count(o => o.RECEIVE_NAME != null),
SHIPMENT = (x.SHIPMENT)
} );
return query;
SHIPMENT = (x.SHIPMENT)
Well you are within a grouping when you try to make that assignment - there are many shipments in each grouping not just one - in fact all shipments for that particular user. Assuming you want a collection of them you could do:
Shipments = g.Select( x=> x.SHIPMENT)
Edit:
If you just want the first shipment for each user (somewhat illogical but fits your data model):
SHIPMENT = g.Select( x=> x.SHIPMENT).First()

Dynamic Linq for dates

I want to build dynamic Linq. Following is my code which works fine for one date. But user can select many dates from calendar. And I need to make Linq for all those selected dates.
saleDate = calendarSales.SelectedDate;
List<SaleDetails> saleDetials = new List<SaleDetails>();
saleDetials = GetSaleDetails();
saleDetials.Where(sale => (Convert.ToDateTime(sale.DATE_TIME).Day == saleDate.Day &&
Convert.ToDateTime(sale.DATE_TIME).Month == saleDate.Month &&
Convert.ToDateTime(sale.DATE_TIME).Year == saleDate.Year)
).ToList();
How to update this query?
You have to build the predicate for your where clause dynamically.
Take a look at the predicatebuilder.
EDIT
Of cause PredicateBuilder supports AND and OR operators.
When using OR you have to start with the initial value of False:
// building the predicate
var pred = PredicateBuilder.False<SaleDetails>();
foreach (var date in MyDateList)
{
pred = pred.Or(sale => sale.DATE_TIME.Date == saleDate.Date);
}
// finally get the data and filter it by our dynamic predicate
List<SaleDetails> saleDetails = GetSaleDetails().Where(pred).ToList();
I'm not sure you need dynamic LINQ here. You should be able to check Where the sale matches Any of the selected dates, like so:
var saleDates = GetSelectedDate();
List<SaleDetails> saleDetials = new List<SaleDetails>();
saleDetials = GetSaleDetails();
saleDetials.Where(sale => saleDates.Any(date =>
(Convert.ToDateTime(sale.DATE_TIME).Day == date.Day &&
Convert.ToDateTime(sale.DATE_TIME).Month == date.Month &&
Convert.ToDateTime(sale.DATE_TIME).Year == date.Year)
)).ToList();
or checking on the Date property:
var saleDates = GetSelectedDate();
List<SaleDetails> saleDetials = new List<SaleDetails>();
saleDetials = GetSaleDetails();
saleDetials.Where(sale => saleDates.Any(date =>
Convert.ToDateTime(sale.DATE_TIME).Date == date.Date)).ToList();

Case Statements in LINQ query - AnonymousType to String?

I basically have the following:
public ActionResult Search(string searchString, string clientNo, int status = -1)
{
var statusLst = new List<string>();
var statusNoQry = from b in db.Briefs
orderby b.Status
select new
{
status = (
b.Status == 0 ? "Requested" :
b.Status == 1 ? "In Progress" :
"Undefined"
)
};
statusLst.AddRange(statusNoQry.Distinct()); <<--- ERROR HERE
ViewBag.status = new SelectList(statusLst);
var ClientNoLst = new List<string>();
var ClientNoQry = from b in db.Briefs
orderby b.Client_No_
where b.Client_Type == 0
select b.Client_No_;
ClientNoLst.AddRange(ClientNoQry.Distinct());
ViewBag.clientNo = new SelectList(ClientNoLst);
var briefs = from b in db.Briefs
select b;
Session["searchString"] = searchString;
Session["clientNo"] = clientNo;
if (!String.IsNullOrEmpty(searchString))
{
briefs = briefs.Where(s => s.Client_No_.Contains(searchString) || s.Name.Contains(searchString));
}
if ((status > -1) && (status < 10))
{
briefs = briefs.Where(y => y.Status == status);
}
if (string.IsNullOrEmpty(clientNo))
return View(briefs);
else
return View(briefs.Where(x => x.Client_No_ == clientNo));
}
However, I receive the following area:
Error 7 Argument 1: cannot convert from 'System.Linq.IQueryable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<string>'
Status is of type int but I would like to cast it to string for my dropdownlist. I'm quite new to all this, what is the appropriate way of achieving this?
Your selector is returning an anonymous type:
select new
{
status = (
b.Status == 0 ? "Requested" :
b.Status == 1 ? "In Progress" :
"Undefined"
)
};
You need to return a set of strings though. The error is telling you exactly what the problem is.
select
(b.Status == 0 ? "Requested" :
b.Status == 1 ? "In Progress" :
"Undefined");
Edit - You didn't post the rest of the method, but from you have your also not disposing your context object, which can cause problems. Normally you wrap this in a using clause.

Resources