I have the following code that give me data from database:
var t = (from ula in proxy.eUserLoginAttempts
where ula.Date >= DateTime.Now && ula.Email.ToLower().Contains("")
&& ula.User != null
&& ula.User.Client != null
&& ula.User.Client.prStatus == 1
select ula).ToList();
In this case, I would get prStatus from Client entity and I check User and Client object if they are not null. Should I do it or ula.User.Client.prStatus will translate in Inner Join and this check is needless?
Answering your direct question: NO, you should test the nullable first...
About your code, I really do suggest a readable way:
var t = proxy.eUserLoginAttempts
.Where(ula => ula.Date >= DateTime.Now)
.Where(ula => !string.IsNullOrEmpty(ula.Email))
.Where(ula => ula.User != null)
.Where(ula => ula.User.Client != null)
.Where(ula => ula.User.Client.prStatus == 1)
.ToList();
Or even better with C# 6
var t = proxy.eUserLoginAttempts
.Where(ula => ula.Date >= DateTime.Now)
.Where(ula => !string.IsNullOrEmpty(ula.Email))
.Where(ula => ula.User?.Client?.prStatus == 1)
.ToList();
Related
I am doing the below linq query which is costing me a lot and this query is in a loop which I can not avoid and I have to do it in C# which also I can not avoid. I have lot of logic above the linq query and after the query. I wanted to check if I can change anything on the query to improve the performance at least a little bit.
lstDataTable.Where(i => i.Field<int>("ALLL_Snapshot_ID") == 20 &&
i.Field<int>("ALLL_Analysis_Segment_Group_Column_ID") == 5 &&
i.Field<DateTime>("OriginationDate") > startingSnapshotDate &&
i.Field<DateTime>("OriginationDate") <= endingSnapshotDate &&
snapshotDataWithDate.Select(j => j.Field<string>
("MaturityDateBorrowerIdNoteNumberKey")).Contains(i.Field<string>
("MaturityDateBorrowerIdNoteNumberKey")) &&
snapshotDataWithDate.Select(j => j.Field<string>
("OriginationDateBorrowerIdNoteNumberKey")).Contains(i.Field<string>
("OriginationDateBorrowerIdNoteNumberKey")))
.Select(i => i.Field<Decimal>("BalanceOutstanding") + i.Field<Decimal>
("UndisbursedCommitmentAvailability")).Sum();
where lstDataTable and snapshotDataWithDate are IEnumerable of DataRow.
I tried above query using join but it is not joining properly. The difference between the two results is way high. Below is the query I tried using join
(from p in lstDataTable
join t in snapshotDataWithDate on p.Field<string>
("MaturityDateBorrowerIdNoteNumberKey") equals t.Field<string>
("MaturityDateBorrowerIdNoteNumberKey") &&
p.Field<string>("OriginationDateBorrowerIdNoteNumberKey") equals
t.Field<string>("OriginationDateBorrowerIdNoteNumberKey")
where p.Field<int>("ALLL_Analysis_Segment_Group_Column_ID") ==
SegmentGroupCECLSurvivalRateObj.ALLL_Segment_Group_Column_ID &&
p.Field<DateTime>("OriginationDate") > startingSnapshotDate &&
p.Field<DateTime>("OriginationDate") <= endingSnapshotDate
select p.Field<Decimal>("BalanceOutstanding") + p.Field<Decimal>
("UndisbursedCommitmentAvailability")).Sum();
Try this query, I have changed some expressions in where clause.
lstDataTable.Where(i => i.Field<int>("ALLL_Snapshot_ID") == 20 &&
i.Field<int>("ALLL_Analysis_Segment_Group_Column_ID") == 5 &&
i.Field<DateTime>("OriginationDate") > startingSnapshotDate &&
i.Field<DateTime>("OriginationDate") <= endingSnapshotDate &&
snapshotDataWithDate.Any(j => j.Field<string>
("MaturityDateBorrowerIdNoteNumberKey") == i.Field<string>
("MaturityDateBorrowerIdNoteNumberKey")) &&
snapshotDataWithDate.Any(j => j.Field<string>
("OriginationDateBorrowerIdNoteNumberKey") == i.Field<string>
("OriginationDateBorrowerIdNoteNumberKey")))
.Select(i => i.Field<Decimal>("BalanceOutstanding") + i.Field<Decimal>
("UndisbursedCommitmentAvailability")).Sum();
Perhaps pulling out the Field accesses will provide a small amount of optimization?
var snapshotDataConvertedMDB = snapshotDataWithDate.Select(r => r.Field<string>("MaturityDateBorrowerIdNoteNumberKey")).ToList();
var snapshotDataConvertedODB = snapshotDataWithDate.Select(r => r.Field<string>("OriginationDateBorrowerIdNoteNumberKey")).ToList();
var ans = lstDataTable
.Select(r => new {
ALLL_Snapshot_ID = r.Field<int>("ALLL_Snapshot_ID"),
ALLL_Analysis_Segment_Group_Column_ID = r.Field<int>("ALLL_Analysis_Segment_Group_Column_ID"),
OriginationDate = r.Field<DateTime>("OriginationDate"),
MaturityDateBorrowerIdNoteNumberKey = r.Field<string>("MaturityDateBorrowerIdNoteNumberKey"),
OriginationDateBorrowerIdNoteNumberKey = r.Field<string>("OriginationDateBorrowerIdNoteNumberKey"),
BalanceOutstanding = r.Field<Decimal>("BalanceOutstanding"),
UndisbursedCommitmentAvailability = r.Field<Decimal>("UndisbursedCommitmentAvailability")
})
.Where(i => i.ALLL_Snapshot_ID == 20 &&
i.ALLL_Analysis_Segment_Group_Column_ID == 5 &&
i.OriginationDate > startingSnapshotDate &&
i.OriginationDate <= endingSnapshotDate &&
snapshotDataConvertedMDB.Contains(i.MaturityDateBorrowerIdNoteNumberKey) &&
snapshotDataConvertedODB.Contains(i.OriginationDateBorrowerIdNoteNumberKey))
.Select(i => i.BalanceOutstanding + i.UndisbursedCommitmentAvailability)
.Sum();
I am trying to filter a data service using a List, however, I get a few error messages. Is there a way to filter by a List with a DataServiceQuery?
DataServiceQuery<Order> ordersQuery = (from x in entities.Orders
.Expand<DataServiceCollection<Shipment>>(a => a.Shipments)
.Expand<DataServiceCollection<OrderItem>>(a => a.OrderItems)
.Expand<OrderStatus>(a => a.OrderStatus)
.Expand<Customer>(a => a.Customer)
.Expand<Store>(a => a.Store)
.Expand<Marketplace>(a => a.Marketplace)
.Expand("Shipments/Carrier")
where x.OrderStatusID != 4
select x) as DataServiceQuery<Order>;
if (beginDate != null && endDate != null)
ordersQuery = ordersQuery.Where(x => x.CreateDate >= beginDate && x.CreateDate <= endDate) as DataServiceQuery<Order>;
if (statuses != null && statuses.Count() > 0)
ordersQuery = ordersQuery.Where(a => stores.Contains(a.OrderStatus.Name)) as DataServiceQuery<Order>;
if (stores != null && stores.Count() > 0)
ordersQuery = ordersQuery.Where(a => stores.Contains(a.Store.StoreName)) as DataServiceQuery<Order>;
if (!String.IsNullOrWhiteSpace(orderNumber))
ordersQuery = ordersQuery.Where(a => a.OrderNumber == orderNumber) as DataServiceQuery<Order>;
That code fails with
Error translating Linq expression to URI: The method 'Contains' is not supported.
This code also fails:
if (statuses != null && statuses.Count() > 0)
{
var statusFilterList = statuses.Select(title => String.Format("(Name eq {0})", title));
var statusFilter = String.Join(" or ", statusFilterList);
ordersQuery.AddQueryOption("$filter", statusFilter).Execute().ToList();
}
Can't add query option '$filter' because it would conflict with the query options from the translated Linq expression.
This code works but it's super slow. I'm using the Entity Framework 5.0. So, Using only Linq or Lambda, how do I combine both pieces of code to return List<Entity> e?
CMSEntities c = new CMSEntities();
var p = c.Entities.Where(
x => x.Address != null
&& x.Address.AddressType != null
&& x.Address.AddressType.AddressTypeID == 1
&& x.Tags.FirstOrDefault() != null)
.ToList();
List<Entity> e = new List<Entity>();
foreach (var a in p)
{
var d = a.Tags.Where(y => y.Feature.FeatureID == 39).FirstOrDefault();
if (d != null)
{
e.Add(a);
}
}
var e = c.Entities.Where(
x => x.Address != null
&& x.Address.AddressType != null
&& x.Address.AddressType.AddressTypeID == 1
&& x.Tags.FirstOrDefault(y => y.Feature.FeatureID == 39) != null
).ToList();
You can directly do it in one query. But I don't know if its going to make big speed difference.
As per Jon's suggestion in comments, this reads better by using Any instead of FirstOrDefault. Like:
var e = c.Entities.Where(
x => x.Address != null
&& x.Address.AddressType != null
&& x.Address.AddressType.AddressTypeID == 1
&& x.Tags.Any(y => y.Feature.FeatureID == 39)
).ToList();
Just get rid of the .ToList() call, and the performance should improve significantly.
I'm guessing that the "null" checks are unnecessary but without looking at your EDM/DataModel this is pure speculation.
var e = c.Entities.Where(
x => x.Address.AddressType.AddressTypeID == 1
&& x.Tags.Any(y => y.Feature.FeatureID == 39)
);
foreach (var a in p)
{
var d = a.Tags.Where(y => y.Feature.FeatureID == 39).FirstOrDefault();
if (d != null)
{
e.Add(a);
}
}
Please see the code below:
var pcPageList = db.PcPages
.Where(m =>
m.Quarter == exactQuarter &&
m.Url == pageUrl &&
m.UpdatedOn.ToDateTime().Date.ToString("dd/MMM").ToLower() == "02/nov")
.OrderBy(m => m.UpdatedOn)
.FirstOrDefault();
When I run this above, the application throws error says: "ToDateTime" is not implemented yet. Anyone please can advice ?
How about:
var updateStart = DateTime.ParseExact("02/nov", "dd/MMM", CultureInfo.InvariantCulture);
var updateEnd = updateStart.AddDays(1.0);
var pcPageList = db.PcPages
.Where(m =>
m.Quarter == exactQuarter &&
m.Url == pageUrl &&
m.UpdatedOn >= updateStart &&
m.UpdatedOn < updateEnd)
.OrderBy(m => m.UpdatedOn)
.FirstOrDefault();
I think, you should be calling ToDateTime using Convert class as:
Convert.ToDateTime(m.UpdatedOn).Date...
And remove the Date in between as:
Convert.ToDateTime(m.UpdatedOn).ToString("dd/MMM").ToLower() == "02/nov"
Rather than doing a string comparison, it would be more efficient to compare the date components directly. I haven't tested this, but something like the following may work:
var pcPageList = db.PcPages
.Where(m => m.Quarter == exactQuarter && m.Url == pageUrl)
// You may need to materialize the results of the query at this point
// or use Convert.ToDateTime(...) instead of ToDateTime()
.Select(m => new { Row = m, UpdatedOn = m.UpdatedOn.ToDateTime() })
.Where(a => a.UpdatedOn.Month == 11 && a.UpdatedOn.Day == 2)
.Select(a => a.Row)
.OrderBy(m => m.UpdatedOn)
.FirstOrDefault();
I'm trying to pass a null value from a RenderAction to another view. But in between, at the controller, my linq lambda expression is not loading the right field, despite the null value going through correctly..
SprintManager.cshtml
<div id="Global_Backlog_Board" class="Board_Panel">
#{Html.RenderAction("ListOfSingleCards", new
{
State_ID = 1
});}
</div>
HomeController.cs
public PartialViewResult ListOfSingleCards( int? Sprint_ID,
int State_ID = 1)
{
var Cards = db.Cards.Where(x => x.State_ID == State_ID &&
x.Sprint_ID == Sprint_ID &&
x.Deleted != 1 &&
x.Archive != 1).ToList();
return PartialView(Cards);
}
So Sprint_ID is being passed over and loaded as null here, but I can't get the query to load the rows correctly.
In fact, the following works:
var Cards = db.Cards.Where(x => x.State_ID == State_ID &&
x.Sprint_ID == null &&
x.Deleted != 1 &&
x.Archive != 1).ToList();
So I suppose I could check if Sprint_ID is null and depending on the result run one of the two seperate queries, but I'd like to understand why my original attempt is not working.
Thank you!
I don't know the correct answer but based on your solution you should be able to tidy it up:
var cards = new List<Card>();
var query = db.Cards.Where(x => x.State_ID == State_ID &&
x.Deleted != 1 &&
x.Archive != 1);
if (Sprint_ID.HasValue)
query = query.Where(x => x.Sprint_ID == Sprint_ID);
else
query = query.Where(x => x.Sprint_ID == null);
cards = query.ToList();
A nullable int won't return "null" in the way that you're thinking. You have to check the HasValue property of it to determine if there is a value, and if so then use it otherwise use null:
public PartialViewResult ListOfSingleCards( int? Sprint_ID,
int State_ID = 1)
{
var Cards = db.Cards.Where(x => x.State_ID == State_ID &&
x.Sprint_ID == Sprint_ID.HasValue ? Sprint_ID.Value : null &&
x.Deleted != 1 &&
x.Archive != 1).ToList();
return PartialView(Cards);
}
Until something better comes a long, I'm using this:
var Cards = new List<Card>();
if (Sprint_ID == null)
{
Cards = db.Cards.Where(x => x.State_ID == State_ID &&
x.Sprint_ID == null &&
x.Deleted != 1 &&
x.Archive != 1).ToList();
}
else
{
Cards = db.Cards.Where(x => x.State_ID == State_ID &&
x.Sprint_ID == Sprint_ID &&
x.Deleted != 1 &&
x.Archive != 1).ToList();
}