In my data service I want to return just max dateTime and only query the database for that data I need. This will help cutting down the data that the server is returning. But I am not sure about when I use the Get() and the model if that is returning the full data base on the model?
Model
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Templates")]
DataService
public DateTime? GetTemplateMaxModifiedDat()
{
var result = UnitOfWork.GetRepository<Template>().Get()
.Where(t=>t.IsCurrentVersion && t.Status == (short)TemplateMode.Published)
.OrderBy(t => t.TemplateIdMain)
.ThenBy(t => t.TemplateIdNumeric)
.ThenBy(t => t.TemplateIdAlt)
.ToList()
.Select(t => new
{
Modified = t.Modified
})
.Distinct().ToList();
var q = result.OrderByDescending(T => T.Modified).FirstOrDefault();
return q.Modified;
}
updated method
public DateTime? GetTemplateMaxModifiedDate()
{
var result = UnitOfWork.GetRepository<Template>()
.Get(x => x.IsCurrentVersion && x.Status == (short)TemplateMode.Published)
.Max(x => x.Modified);
return result;
}
Related
I have a following query
return _context.Table1
.Where(x => x.ContactId == contactKey.Id)
.Include(x => x.Table2)
.Include(x => x.Table3.Table4)
.Select(a =>
new MyReadModel
{
PriorityAssignment = true,
LastContactedDate = (a.Table3.Table4 != null && a.Table3.Table4.FirstOrDefault(h =>
h.Id == a.Table2.FkId
) != null ?
a.Table3.Table4.FirstOrDefault(h => && h.Id == a.Table2.FkId
).LastContactedDatetime : default
)
}
)
.ToListAsync();
What i wants is to simplify LastContactedDate assignment with in select. I think we can assign
a.Table3.Table4.FirstOrDefault(h =>
h.Id == a.Table2.FkId
)
to some variable but can't able to do it
can someone identify what is needed
With EF Core you don't have to check for null, LINQ Translator do not execute your code, but uses it for translation to the SQL. Also Includes is not needed if you do not retrieve whole objects.
return await _context.Table1
.Where(x => x.ContactId == contactKey.Id)
.Select(a => new MyReadModel
{
PriorityAssignment = true,
LastContactedDate = (DateTime?)a.Table3.Table4.Where(h => h.Id == a.Table2.FkId)
.OrderByDescending(h => LastContactedDatetime)
.Select(h => LastContactedDatetime)
.FirstOrDefault()
}).ToListAsync();
you can use it like this example
List<string> someList= new List<string>();
someList= someList.Select(x =>
{
var newVariable= "newVariable";
return newVariable;
}).ToList();
in your case
return _context.Table1
.Where(x => x.ContactId == contactKey.Id)
.Include(x => x.Table2)
.Include(x => x.Table3.Table4)
.Select(a => {
Table4 newVariable = null;
if(a.Table3.Table4 != null)
newVariable = a.Table3.Table4.FirstOrDefault(h => h.Id == a.Table2.FkId;
var result = new MyReadModel
{
PriorityAssignment = true,
LastContactedDate = (newVariable != null ? newVariable.LastContactedDatetime : default
)
};
}
) .ToListAsync();
I was wondering if there was a way to combine these two. There are two multiple db sets. I've already tried putting with the same variable. Any ideas?
public JsonResult GetProductByPDLN(int pdlnId, int copcCode)
{
_context.Configuration.ProxyCreationEnabled = false;
var prod = _context.ProductLines
.Where(pl => pl.Id == pdlnId)
.Select(p => p.Products)
.ToList();
var copc = _context.ProfitCenters
.Where(c => c.Id == copcCode)
.Select(p => p.ProductLines)
.ToList();
return Json(prod && copc, JsonRequestBehavior.AllowGet);
}
Either create a new class or an anonymous. Something along these lines:
public JsonResult GetProductByPDLN(int pdlnId, int copcCode)
{
_context.Configuration.ProxyCreationEnabled = false;
var prod = _context.ProductLines
.Where(pl => pl.Id == pdlnId)
.Select(p => p.Products)
.ToList();
var copc = _context.ProfitCenters
.Where(c => c.Id == copcCode)
.Select(p => p.ProductLines)
.ToList();
return Json(new {ProductLines = prod, ProfitCenters = copc}, JsonRequestBehavior.AllowGet);
}
I have a LINQ query which has three Where clauses. In each Where clause I am looking up the same set of items in order to compare values:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Where(x => level1Category == 0 || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Contains(level1Category))
.Where(x => !level2Categories.Any() || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Intersect(level2Categories.AsEnumerable()).Any())
.Where(x => !level3Categories.Any() || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Intersect(level3Categories.AsEnumerable()).Any());
Is there a way I can get the value of UmbracoAlias.Items.Categories once and store that value to be used in the other where clauses without causing the GetPropertyValue method to execute more than once?
You can pair up each item with category IDs, like this:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Select(c => new {
Child = c
, CategoryIds = c
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id)
.ToList()
})
.Where(x => level1Category == 0 || x.CategoryIds.Contains(level1Category))
.Where(x => !level2Categories.Any() || x.CategoryIds.Intersect(level2Categories.AsEnumerable()).Any())
.Where(x => !level3Categories.Any() || x.CategoryIds.Intersect(level3Categories.AsEnumerable()).Any())
.Select(x => x.Child);
This does the filtering on children paired up with their category IDs, and then keeps only the Child object in the final projection.
You could further simplify this by combining all three Where clauses:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Where(c => {
var categoryIds = c
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id)
.ToList();
if (level1Category != 0 && !categoryIds.Contains(level1Category)) {
return false;
}
if (level2Categories.Any() && !categoryIds.Intersect(level2Categories.AsEnumerable()).Any()) {
return false;
}
if (level3Categories.Any() && !categoryIds.Intersect(level3Categories.AsEnumerable()).Any()) {
return false;
}
return true;
});
I am trying to return a set of results based on a given date and if that date does not exist then then I want to return the result from the closet past date to that.
I am trying to return the results from an ApiController. The method I am using is pretty slow and I'm sure it's not the best one.
[HttpPost]
public IHttpActionResult GetItemsForDate(DateDTO Date)
{
using (var context = new CafeteriaContext())
{
bool vreauTOT = Date.vreauTOT;
var itemsList = new List<MenuItem>();
var getDates = context.MenuItems.Where(d => d.Date == Date.Date || d.Date < Date.Date).Select(d => d.Date).ToList();
var availableDate = getDates.OrderByDescending(t => t.Date).First();
if (vreauTOT)
{
itemsList = context.MenuItems
.Where(d => d.Date == availableDate)
.Select(r => r)
.ToList();
}
else
{
itemsList = context.MenuItems
.Where(d => d.Date == availableDate)
.Where(d => d.OnlyExternal == false)
.Select(r => r)
.ToList();
}
return Ok(itemsList);
}
Is it possible to save a trip to the database and maybe construct a single query that will return the same results ? Or maybe a faster way than what I am doing right now.
You probably don't need if .. else here. It can be reduced to below using compound condition
itemsList = context.MenuItems
.Where(d => d.Date == availableDate && (!vreauTOT && d => !d.OnlyExternal))
.ToList();
itemsList = context.MenuItems
.Where(d => d.Date == availableDate)
.Select(r => r)
.ToList();
No need to use Select here.
itemsList = context.MenuItems
.Where(d => d.Date == availableDate)
.Where(d => d.OnlyExternal == false)
.Select(r => r)
.ToList();
No need to use Select here.
Use 1 where and check the conditions there:
.Where(d => d.Date == availableDate && ! d.OnlyExternal)
Explanation: each LINQ-method will perform a loop in the background, and the more loops you create, the slower it will run.
I'm currently working on an ASP.NET MVC 4.5 application. I have one question for the Linq Gurus please.
I want to use the .Where Filter only if the importing parameter initOfferList = false. The problem: the PagedList gets only filtered for the first page (10 entries here).
My Linq query looks as follows:
public IPagedList<OfferListVM> GetOfferList(OfferDateSearchVM offerDateSearch, bool initOfferList, int page)
{
var offerList = Db.Offer
.Select(x => new OfferListVM
{
OfferId = x.OfferId,
CreatedDate = x.CreatedDate,
Label = x.OfferData.Label,
})
.OrderBy(x => x.OfferId)
.ToPagedList(page, 10);
if (!initOfferList)
{
offerList = offerList
.Where(x => x.CreatedDate >= offerDateSearch.FromDate && x.CreatedDate <= offerDateSearch.ToDate)
.OrderBy(x => x.OfferId)
.ToPagedList(page, 10);
}
return offerList;
}
How can I modify my query to properly use the .Where clause on all entries, but only when the importing parameter initOfferList = false?
Thank you!
Try:
public IPagedList<OfferListVM> GetOfferList(OfferDateSearchVM offerDateSearch, bool initOfferList, int page)
{
var offerListQuery = Db.Offer.OrderBy(x => x.OfferId);
if (!initOfferList)
{
offerListQuery = offerListQuery
.Where(x => x.CreatedDate >= offerDateSearch.FromDate &&
x.CreatedDate <= offerDateSearch.ToDate
);
}
var offerList = offerListQuery
.Select(x => new OfferListVM
{
OfferId = x.OfferId,
CreatedDate = x.CreatedDate,
Label = x.OfferData.Label,
})
.ToPagedList(page, 10);
return offerList;
}
If I understand correctly, the following should take your boolean flag into account in a single Linq, thus applying the where to the full list before filtering.
var offerList = Db.Offer
.Where(x => initOfferList == true || (initOfferList == false && x.CreatedDate >= offerDateSearch.FromDate && x.CreatedDate <= offerDateSearch.ToDate))
.Select(x => new OfferListVM
{
OfferId = x.OfferId,
CreatedDate = x.CreatedDate,
Label = x.OfferData.Label,
})
.OrderBy(x => x.OfferId)
.ToPagedList(page, 10);