How to compare date in linq c# - c#

i have 'created date' and 'closed date' in my file and i'm converting it in json so i have that dates in json.
in my method i have two parameter like from date and to date and i want to count particular column data of my file between from date and to date.so how can we write code to fetch it using linq.
i tried this...
public JsonResult StatusDerails(DateTime from,DateTime to)
{
string csvurl = WebConfigurationManager.AppSettings["csvfileurl"];
var lines = System.IO.File.ReadAllLines(csvurl).Skip(1);
List<Product> prdt = new List<Product>();
foreach (string line in lines)
{
Product c1 = new Product();
var split = line.Split(',');
c1.ID = Int32.Parse(split[0]);
c1.Area_Path = split[1];
c1.IterationPath = split[2];
c1.State = split[3];
c1.Reason = split[4];
c1.Priority = Int32.Parse(split[5]);
c1.Severity = split[6];
c1.Tags = split[7];
c1.Title = split[8];
c1.CreatedDate = split[9];
c1.CreatedBy = split[10];
c1.ResolvedDate = split[11];
c1.ResolvedBy = split[12];
c1.ClosedDate = split[13];
c1.AssignedTo = split[14];
prdt.Add(c1);
}
//var list = prdt.GroupBy(a=>a.AreaPath).Select(a=>new UIproduct() {
var productName = prdt.Select(a => a.Area_Path).Distinct();
List<StatusDetail> statusdetail = new List<StatusDetail>();
foreach (var Name in productName)
{
StatusDetail sd = new StatusDetail();
sd.CarryOver = prdt.Where(a => a.CreatedDate >= from.Date.ToString() && a.ClosedDate <= to.Date.ToShortDateString
}
return Json(statusdetail, JsonRequestBehavior.AllowGet);
}

The comparison of DateTime as string will not be a good option and that wont gives you the exact result, So I recommend you to change the type of CreatedDate and ClosedDate to DateTime. and compare two DateTime values in linq. I think instead of splitting json for creating object of certain types you can use json converters.
Fix for your scenario:
c1.CreatedDate = DateTime.Parse(split[9]);
c1.ClosedDate = DateTime.Parse(split[13]);
Don't forget to change the type in the class, Now its fine to use the linq as like the following:
sd.CarryOver = prdt.Where(a => a.CreatedDate >= from.Date && a.ClosedDate <= to.Date);

Related

Compare Two Complex List of data

When I am Trying to save current list of data into database, I need to get already existing data from database, and need to compare with current list of data.
I have two lists one is PreviousList(existing data from DB) and other is CurrentList(Modified data)
public class SoftClose
{
public int ID = -1;
public int AID = -1;
public int WFID = -1;
public string PREFIX;
public DateTime SCDATE;
public string STATUS;
}
In CurrentList I modified Prefix to D2 where ID=1 and added new row(Id=4)...
My req is
When I am trying to save CurrentList to Db,
If there is any new Prefix in CurrentList that is not there in PreviousList I need to insert that new row and need to change Status to ADD for that row.
I changed Prefix to D2 where Id = 1 in CurrentList. D1 is there is DB and but not in CurrentList so i need to delete it. So i need to change the status to DELETE for that record. I should not insert D2 record where id=1 becuase D2 is already there. If I changed to D5 where Id = 1 then I need to insert it because D5 is not there in DB So i need to change the status to UPDATE.
How to do this? What is the best approach to compare lists
here is a solution you could try:
List<SoftClose> previousList = new List<SoftClose>(){
new SoftClose(){ID=1, Status = "NO_CHANGE",AID="19", Prefix = "D1"},
new SoftClose(){ID=2, Status = "NO_CHANGE",AID="20", Prefix = "D2"},
new SoftClose(){ID=3, Status = "NO_CHANGE",AID="21", Prefix = "D3"}
};
List<SoftClose> currentList = new List<SoftClose>(){
new SoftClose(){ID=1, Status = "NO_CHANGE",AID="19", Prefix = "D2"},
new SoftClose(){ID=2, Status = "NO_CHANGE",AID="20", Prefix = "D2"},
new SoftClose(){ID=3, Status = "NO_CHANGE",AID="21", Prefix = "D6"},
new SoftClose(){ID=4, Status = "NO_CHANGE",AID="22", Prefix = "D4"},
new SoftClose(){ID=5, Status = "NO_CHANGE",AID="22", Prefix = "D5"}
};
var addlist = currentList.Where(c => previousList.All(p => !p.ID.Equals(c.ID) && !p.Prefix.Equals(c.Prefix)));
foreach(var n in addlist)
{
var index = currentList.FindIndex(p => p.Prefix.Equals(n.Prefix));
currentList[index].Status = "ADD";
}
var updateORdeletelist = currentList.Where(c => c.Status.Equals("NO_CHANGE") && previousList.Exists(p => p.ID.Equals(c.ID) && !p.Prefix.Equals(c.Prefix)));
foreach (var n in updateORdeletelist)
{
var index = currentList.FindIndex(p => p.Prefix.Equals(n.Prefix));
if (previousList.FindIndex(p => p.Prefix.Equals(n.Prefix)) < 0)
currentList[index].Status = "UPDATE";
else
currentList[index].Status = "DELETE";
}
foreach (var item in currentList)
{
Console.WriteLine($"Id:{item.ID}, Desc1:{item.Prefix}, Status:{item.Status}");
}
output
Id:1, Desc1:D2, Status:DELETE
Id:2, Desc1:D2, Status:NO_CHANGE
Id:3, Desc1:D6, Status:UPDATE
Id:4, Desc1:D4, Status:ADD
Id:5, Desc1:D5, Status:ADD
There is a tool called Side by Side SQL Comparer in C# at https://www.codeproject.com/Articles/27122/Side-by-Side-SQL-Comparer-in-C.
basic use of the component:
using (TextReader tr = new StreamReader(#"c:\1.sql"))
{
sideBySideRichTextBox1.LeftText = tr.ReadToEnd();
}
using (TextReader tr = new StreamReader(#"c:\2.sql"))
{
sideBySideRichTextBox1.RightText = tr.ReadToEnd();
}
sideBySideRichTextBox1.CompareText();
You load the left and right sides to their respective variables sideBySideRichTextBox1.LeftText and sideBySideRichTextBox1.RightText and compare them with sideBySideRichTextBox1.CompareText();
In your case the 1.sql and 2.sql would be your PreviousList and CurrentList -database files.
There is more detailed documentation at the project-site.

How to apply multiple optional filters in a LINQ query

I have a page where user can select any number of search filters to apply search
When user clicks on search, these parameters are passed to my GetIndicatorData method to perform the query. However, it doesn't seem to work for me.
Here is my code
public static List<tblindicators_data_custom> GetIndicatorsData(string status, int service_id, int operator_id, string year, string frequency)
{
var date = Convert.ToDateTime(year + "-01-01");
int[] numbers = status.Split(',').Select(n => int.Parse(n)).ToArray();
var ict = new ICT_indicatorsEntities();
var result = from ind in ict.tblindicators_data
join ser in ict.tblservices on ind.service_id equals ser.Id
join oper in ict.tbloperators on ind.operator_id equals oper.Id
where numbers.Contains(ind.status) && (ind.date_added.Year == date.Year)
select new
{
ind.Id,
ind.service_id,
ind.survey_id,
ind.operator_id,
ind.type,
ind.date_added,
ind.quater_start,
ind.quater_end,
ind.status,
ind.month,
service = ser.name,
operator_name = oper.name
};
List<tblindicators_data_custom> data = new List<tblindicators_data_custom>();
foreach (var item in result)
{
tblindicators_data_custom row = new tblindicators_data_custom();
row.Id = item.Id;
row.survey_id = item.survey_id;
row.service_id = item.service_id;
row.service_name = item.service;
row.operator_id = item.operator_id;
row.operator_name = item.operator_name;
row.date_added = item.date_added;
row.quater_start = item.quater_start;
row.type = item.type;
row.quater_end = item.quater_end;
row.month = item.month == null? DateTime.Now:item.month;
row.status = item.status;
data.Add(row);
}
return data;
}

Convert string array to another type

I'm trying to convert the string separated by commas which has 7 values of:
2014-21-2,1207.81,1209.87,1202.84,1203.79,1862300,1203.79
To another model which is:
return lines[1].Split(',').Select(i => new StockModel
{
StockDate = DateTime.ParseExact(i.ToString(), "yyyy-MM-dd", null),
StockOpen = float.Parse(i.ToString()),
StockHigh = float.Parse(i.ToString()),
StockLow = float.Parse(i.ToString()),
StockClose = float.Parse(i.ToString()),
StockVolume = Convert.ToInt32(i.ToString()),
StockAdjustedClose = float.Parse(i.ToString()),
StockSymbol = stockSymbol
}).SingleOrDefault();
However I get errors such as: Additional information: Input string was not in a correct format. http://s17.postimg.org/ro4k3tzct/Screenshot_1.png
If I do it manually like: DateTime date = DateTime.Parse(lines[1].Split(',')[0]), it works fine.
Whatever value I'm trying to put into the new Model, I get errors such as this one.
OK, I see the problem. You shouldn't use Select here. Try following instead:
var i = lines[1].Split(',');
return new StockModel()
{
StockDate = DateTime.ParseExact(i[0].ToString(), "yyyy-MM-dd", null),
StockOpen = float.Parse(i[1].ToString()),
StockHigh = float.Parse(i[2].ToString()),
StockLow = float.Parse(i[3].ToString()),
StockClose = float.Parse(i[4].ToString()),
StockVolume = Convert.ToInt32(i[5].ToString()),
StockAdjustedClose = float.Parse(i[6].ToString()),
StockSymbol = stockSymbol
};

Using List<int> in Url.Action Method

i am writing code for search page and i have to pass some filters to the action and depending on those input I have to generate hyper links, hence i am using Url.Action function to generate links.
below is my code
#Url.Action("Index","Search",new SkillKindleWeb.ViewModels.Search.SearchRawInput()
{
CategoryIds = Model.Request.CategoryIds,
SubCategoryIds = Model.Request.SubCategoryIds,
StartDate = Model.Request.StartDate,
EndDate = Model.Request.EndDate,
StartPrice = Model.Request.StartPrice,
LocationGroupIds = Model.Request.LocationGroupIds,
LocationIds = Model.Request.LocationIds,
EndPrice = Model.Request.EndPrice,
City = Model.Request.City,
PageNo = 1,
SearchQuery = Model.Request.SearchQuery,
Segment1 = Model.Request.Segment1,
Segment2 = Model.Request.Segment2,
TargetAge = Model.Request.TargetAge
})
and it is generating url like this
http://someDomain.com/ncr/classes?CategoryIds=System.Collections.Generic.List%601%5BSystem.Int32%5D&StartDate=03%2F30%2F2013%2000%3A00%3A00&StartPrice=0&EndPrice=140000&PageNo=2
My expected Url was
http://SomeDomain.com/ncr/classes?CategoryIds=9&StartDate=3/30/2013&StartPrice=0&EndPrice=140000
What about converting it to string representation yourself like that:
#Url.Action("Index","Search",new SkillKindleWeb.ViewModels.Search.SearchRawInput()
{
CategoryIds = string.Join(",", Model.Request.CategoryIds),
SubCategoryIds = string.Join(",", Model.Request.SubCategoryIds),
StartDate = Model.Request.StartDate.ToShortDateString(),
EndDate = Model.Request.EndDate.ToShortDateString(),
StartPrice = Model.Request.StartPrice,
LocationGroupIds = Model.Request.LocationGroupIds,
LocationIds = Model.Request.LocationIds,
EndPrice = Model.Request.EndPrice,
City = Model.Request.City,
PageNo = 1,
SearchQuery = Model.Request.SearchQuery,
Segment1 = Model.Request.Segment1,
Segment2 = Model.Request.Segment2,
TargetAge = Model.Request.TargetAge
})
That is what a viewmodel should be for. That you convert and format all the values you need in the way the view expects it.
Notice that I added a ToShortDateString() to your dates as well, since it seems you are not interested in the time part.

Linq over InputStream from HttpPostedFileWrapper

Is it possible to apply a Linq query from a HttpPostedFileWrapper?
My web app allows users to select a bunch of .csv files. I now need to open those files and import them.
My previous code, which uses paths and file names looks like;
importedList = (from csvLine in File.ReadAllLines(fileName)
let x = csvLine.Split(',')
select new ImportedXDock
{
StoreNumber = int.Parse(x[0]),
DCNumber = int.Parse(x[1]),
DeliveryDay = x[2],
Activity = x[3],
ActivityDay = x[4],
Time = TimeSpan.Parse(x[5])
}).ToList();
However, now that i have a collection of HttpPostedFileWrapper objects how would I do the same?
edit
Or do I need to convert it to something and then read the file?
You may be able to loop over the file names instead of the input streams
foreach (var fileName in wrapper.Select(w => w.FileName))
{
yield return (from csvLine in File.ReadAllLines(fileName)
let x = csvLine.Split(',')
select new ImportedXDock
{
StoreNumber = int.Parse(x[0]),
DCNumber = int.Parse(x[1]),
DeliveryDay = x[2],
Activity = x[3],
ActivityDay = x[4],
Time = TimeSpan.Parse(x[5])
}).ToList();
}

Categories