searching a date list - c#

I have a collection list which contains the following fields
Date1
Xvalue
Yvalue
I want to seach within this list against another date list. For every date in the second list I want to get records starting between this minimum date and the next date is which (30 minutes to the minium date).
foreach (var item in selectedDates.Where(x => x.Checked))
{
// item.minDate is my starting date
// I want all records between item.minDate and 30 minutes added to it)
var t = lf.ReplicateBlocks.FindAll(o=> o.minimumCompletionDate >= item.
}
**UPDATE**
public class ReplicateBlock
{
public int ReplicateId { get; set; }
public string AssayNumber { get; set; }
public DateTime InitiationDate { get; set; }
public DateTime InitiationTime { get; set; }
public DateTime minimumCompletionDate { get; set; }
public DateTime minimumCompletionTime { get; set; }
public string correctedCount { get; set; }
public string moduleName { get; set; }
public string exception { get; set; }
}
public class RunLogEntryDatesDisplay
{
public DateTime runDate { get; set; }
public String DateRange { get; set; }
public bool Checked { get; set; }
public string MinimumReplicateId { get; set; }
}
The final output I am looking for is a revised Replicate Block list. RunLogEntryDatesDisplay is a checkbox list posted from the view. In this list I look at the checked date which is runDate and starting from the first selection I add 30 minutes to it and find all records in ReplicateBlock List in between and the edges. I will do the same for every selected date in the checbox list and in the end will have a final/filtered ReplicateBlockLisr based on users selections(checked item).

You could loop through the dates and populate a result list:
List<ReplicateBlock> blocks = new List<ReplicateBlock>();
foreach (var item in selectedDates.Where(x => x.Checked))
{
var t = lf.ReplicateBlocks.Where(o=>
o.minimumCompletionDate >= item.minDate &&
o.minimumCompletionDate <= item.minDate.AddMinutes(30));
blocks.AddRange(t);
}
You could also do it in one query:
var query = from d in selectedDates
from o in lf.ReplicateBlocks
where d.Checked &&
o.minimumCompletionDate >= d.minDate &&
o.minimumCompletionDate <= d.minDate.AddMinutes(30))
select o;

Related

Iterate over Entity Framework object properties

I have a table "StaffMembers" that have columns indicating the number of days worked in a month, the properties in the model are as follows:
public class StaffMember
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Phone { get; set; }
public string Email { get; set; }
public string BirthDate { get; set; }
public int OctDays { get; set; }
public int NovDays { get; set; }
public int DecDays { get; set; }
public int JanDays { get; set; }
public int FebDays { get; set; }
public int MarDays { get; set; }
public int AprDays { get; set; }
}
now I retrieve the specific staffMember using linq:
var staffMember = (from b in db.StaffMembers
where b.Id == Id
select b).FirstOrDefault();
what I want to do is to loop over the months properties in staffMember and add all the worked days together to get total working days in the year.
for example if he worked 10 days in oct and 20 days in dec and 30 days in jan, I want a way to iterate over the months and sum the days.
You can do it by iterating over object properties and apply your condition on it.
static void Main(string[] args)
{
var staffA = new StaffMember();
int totalWorkDays = 0;
staffA.AprDays = 5;
staffA.FebDays = 7;
foreach (var item in staffA.GetType().GetProperties())
{
if (item.Name.EndsWith("Days"))
{
totalWorkDays += (int)item.GetValue(staffA)!;
}
}
Console.WriteLine(totalWorkDays);
}
this snippet prints ( 5 + 7 ) => 12
You can use reflection to iterate over the properties, but I do not recommend this because you have to point anyway which properties you want to take into consideration. That's because you have multiple integer properties like Id and Phone so you cannot indicate in the loop that you want to sum integer properties, you have to show explicitly that you want to sum OctDays etc. or write some algorithms that indicates that the current property is responsible for the month. So the best way (and in my opinion simplier than reflection way) would be just to get each of the month explicit and sum like this:
var sum = staffMember.OctDays + staffMember.NovDays + staffMember.DecDays + staffMember.JanDays + staffMember.FebDays + staffMember.MarDays + staffMember.AprDays

Entity Framework Select top row from each type based on subobject value

I am using EF6 Code First approach. I have a the following related tables Events, Markets, MarketTypes with these models
public class Event
{
public Guid ID { get; set; } = Guid.NewGuid();
public List<Market> Markets { get; set; } = new List<Market>();
}
public class Market
{
public Guid ID { get; set; } = Guid.NewGuid();
public Guid EventID { get; set; }
public Event Event { get; set; }
public Guid TypeID { get; set; }
public MarketType Type { get; set; }
public DateTime InitiateDateTime { get; set; }
public DateTime LastUpdateDateTime { get; set; }
public double Value { get; set; }
}
public class MarketType
{
public Guid ID { get; set; } = Guid.NewGuid();
public string Name { get; set; }
public int Order { get; set; }
}
Each event have many markets and each market has one type. I am using the following statement to get list of events.
List<Event> events = new List<Event>();
var startDate = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day);
var endDate = startDate.AddHours(24);
events = _context.Events
.Include(e => e.Markets)
.Include(e => e.Markets.Select(i => i.Type))
.Where(e => e.DateTime >= startDate)
.Where(e => e.DateTime < endDate)
.OrderBy(e => e.DateTime)
.ToList();
Is it possible to update the above query in order to retrieve one market row of each type which is the last updated one (having largest 'LastUpdateDateTime' value). I am currently doing this through an ugly manual method.
if your want last updated values, I use in this case OrderByDescending, that will be sort a list with last .
like this:
_context.Events
.Inlcude(e=>e.Markets)
.Include(e=>e.Markets.Select(I=>I.Type))
.Where(e=>e.DateTime>= startDate && e.DateTime<endDate)
.OrderBy(e.DateTime)
.OrderByDescending(e.LastUpdateDateTime )
.ToList();
you can't use ThenbBy linq cmd because OrderBy is for ascending and it is in conflict with OrderByDescending.
with this you have a list.
After you need the cmd First() or FirstOrDefault() to get only the largest one.
I am not sure but if you use cmd FirstOrDefault() instead of where cmd it could be work.
is it good for you?

Using part of the Date in a ViewSource Grouping Description WPF C#

I have a ViewSource based on an observable collection of a set of objects based on a c# class called "Ticket" for a DataGrid for a WPF project in C# .net 4. The project is for a simple Helpdesk app.
The ViewSource Grouped on a Property call TktDate and all the tickets entered that day obviously grouped together in my DataGrid
However I have recently updated the code so the TktDate now not only stores the Date element but also the Time element, so clearly when I mean to Group on the Date only I am failing to do this because of the time elements (Am I correct?).. So if that was not clear here is a screen shot
Is there a way to Group on the date part TktDate and ignore the time element for my ViewSource or must I add a new property to my class to store the date part only and group on the new property?
See the properties of the class below
public class Ticket : INotifyPropertyChanged
{
public int userid { get; set; }
public int deptid { get; set; }
public int topicid { get; set; }
public int staffid { get; set; }
public int priorityid { get; set; }
public string poster { get; set; }
public DateTime TktDate { get; set; }
public string title { get; set; }
public string bodyopen { get; set; }
public string bodyclose { get; set; }
public string timespent { get; set; }
public string dayoffset { get; set; }
public string sysdt { get; set; }
public string Netdt { get; set; }
public string Teldt { get; set; }
public string Clidt { get; set; }
public string status { get; set; }
private string ticket;
public string Tket
In the ViewSource I group on the TktDate, which records the date the ticket is created. The grouping code is below and it worked fine
CollectionViewSource ticketViewSource = ((CollectionViewSource)(this.FindResource("ticketViewSource")));
ticketViewSource.Source = TicketCol;
ticketDataGrid.DataContext = ticketViewSource;
//add grouping
if (ticketViewSource != null)
{
ticketViewSource.GroupDescriptions.Clear();
ticketViewSource.GroupDescriptions.Add(new PropertyGroupDescription("TktDate"));
ticketViewSource.SortDescriptions.Clear();
ticketViewSource.SortDescriptions.Add(new SortDescription("TktDate", ListSortDirection.Ascending));
}
Is there a way to Group on the date part TktDate and ignore the time element for my ViewSource or must I add a new property to my class to store the date part only and group on the new property?
You may try to group by a nested property:
ticketViewSource.GroupDescriptions.Add(new PropertyGroupDescription("TktDate.Date"));
If this doesn't work you should add a new DateTime read-only property to your Ticket class that returns TktDate.Date and group by this one.

Understanding MongoDb .NET driver indexing

I'm currently working on an application where MongoDb is used for quite a large amount of data.
The objects I'm storing in MongoDb looks like this:
public class PowerPlantDataReading
{
[BsonId]
public int ID { get; set; }
[BsonElement("EDIEL")]
public string EDIEL { get; set; }
[BsonElement("EndDate")]
public DateTime EndDate { get; set; }
[BsonElement("Created")]
public DateTime Created { get; set; }
[BsonElement("DataReading")]
public DataReading DataReading { get; set; }
}
public class DataReading
{
[BsonElement("Version")]
public int Version { get; set; }
[BsonElement("OriginalId")]
public int OriginalId { get; set; }
[BsonElement("Unit")]
public string Unit { get; set; }
[BsonRepresentation(MongoDB.Bson.BsonType.Double)]
[BsonElement("Quantity")]
public decimal Quantity { get; set; }
[BsonElement("Quality")]
public string Quality { get; set; }
[BsonElement("StartDate")]
public DateTime StartDate { get; set; }
}
And the query I'm running against MongoDb looks like this:
DateTime startDateUtc = DateTime.UtcNow.AddDays(-5);
DateTime endDateUtc = DateTime.UtcNow;
var queryBuilder = Builders<PowerPlantDataReading>.Filter;
var filter = queryBuilder.Where(x => x.EndDate >= startDateUtc && x.EndDate < endDateUtc);
var query = collection.Find(filter).ToListAsync();
return query.Result;
The query returns around 825.000 objects, but takes well over 4 minutes to run.
I then tried to create an index like this:
IMongoCollection<PowerPlantDataReading> collection = GetCollection();
collection.Indexes.CreateOne(Builders<PowerPlantDataReading>.IndexKeys.Descending(x => x.EndDate));
Then ran the query again, but to my surprise, it didn't make a difference at all.
I'm not sure if I'm creating the index correctly? If not, how should I create my index to get the best possible performance for the query?
Thanks in advance.

Pass through list by period

I have a List<Items> for example 365 elements
public DateTime DayD { get; set; }
public double Day { get; set; }
public double Week { get; set; }
public double Month { get; set; }
How to pass through the list by period 30 day - mean for each element select next 30 element.
I would use LINQ with a yield return, something like :
static IEnumerable<List<Item>> GetXMany(int pageSize)
{
for (int i = 0; i < items.Count(); i+=pageSize)
{
yield return items.Skip(i).Take(pageSize).ToList();
}
}
and loop through it with :
foreach (List<Item> items in GetXMany(30))
{
}

Categories