I pass a list of class to the Stimulsoft report inside the Bussines object.
I do not have any issues in the report file.
When I render report variables fill current and the list of columns repeated but the data don't display.
I don't have any errors in action!
The type of columns in class is Double and The type of fields of report is Float.
Action code :
public ActionResult PumpsStatusDailySummarySnapshot()
{
try
{
DateTime dateTimeStart = (DateTime)Session[_sessionList.PumpsStatusDailySummaryDateTimeStart];
DateTime dateTimeEnd = (DateTime)Session[_sessionList.PumpsStatusDailySummaryDateTimeEnd];
string time = Session[_sessionList.PumpsStatusDailySummaryTime] as string;
List<PumpsStatu> pumpsStatus = new List<PumpsStatu>();
int pumpCount;
using (SPMSEntities db = new SPMSEntities())
{
pumpCount = db.Packages.First().TotalPumpCount;
}
if (HttpContext.Cache[_cacheList.PumpsStatusDailySummary] == null)
{
using (SPMSEntities db = new SPMSEntities())
{
pumpsStatus = db.PumpsStatus.ToList();
HttpContext.Cache.Insert(_cacheList.PumpsStatusDailySummary, pumpsStatus, null, DateTime.Now.AddMinutes(15),
Cache.NoSlidingExpiration);
}
}
else
{
pumpsStatus = HttpContext.Cache[_cacheList.PumpsStatusDailySummary] as List<PumpsStatu>;
}
pumpsStatus = pumpsStatus.Where(x => x.Date >= dateTimeStart && x.Date <= dateTimeEnd).ToList();
//Collect report data
List<PumpsStatusDailySummaryClass> list = new List<PumpsStatusDailySummaryClass>();
List<PumpsStatusDailySummaryClass> reportList = new List<PumpsStatusDailySummaryClass>();
DateTime dateTimeTemp = dateTimeStart;
int preDay = -1;
int prePumpCountInWork = 1;
long currentId = 0;
long lastItemId = pumpsStatus.Last().Id;
int runTime = 0;
foreach (var item in pumpsStatus)
{
currentId = item.Id;
//تاریخ امروز ؟
int dayOfYear = item.Date.DayOfYear;
if (preDay == -1)
{
preDay = dayOfYear - 1;
}
//======================================================================
if (item.Frequency1 > 0)
{
PumpsStatusDailySummaryClass dailySummary = new PumpsStatusDailySummaryClass();
dailySummary.Current = item.Current1;
dailySummary.Efficiency = item.Efficiency1; //calc
dailySummary.Frequency = item.Frequency1;
//dailySummary.RunTime = 1;
dailySummary.Power = item.Power1;
dailySummary.Flow =
item.Frequency1 == 41 ? 65 :
item.Frequency1 == 42 ? 69 :
item.Frequency1 == 43 ? 74 :
item.Frequency1 == 44 ? 78 :
item.Frequency1 == 45 ? 85 :
item.Frequency1 == 46 ? 88 :
item.Frequency1 == 47 ? 92 :
item.Frequency1 == 48 ? 97 :
item.Frequency1 == 49 ? 101 : 50;
dailySummary.SolarDate = item.SolarDateTime;
dailySummary.Id = (int)item.Id;
list.Add(dailySummary);
}
//======================================================================
//Fill date
if (dayOfYear - preDay > 1 || dayOfYear < preDay || item.Id == lastItemId)
{
if (list.Count == 0)
{
continue;
}
PumpsStatusDailySummaryClass dailySummary = new PumpsStatusDailySummaryClass();
dailySummary.Current = Math.Round(list.Average(x => x.Current), 1);
dailySummary.Efficiency = Math.Round(list.Average(x => x.Efficiency), 1);
dailySummary.Frequency = Math.Round(list.Average(x => x.Frequency), 1);
dailySummary.Power = Math.Round(list.Average(x => x.Power), 1);
dailySummary.RunTime = list.Count / 60;
dailySummary.SolarDate = list.First().SolarDate;
dailySummary.Flow = Math.Round(list.Average(x => x.Flow), 1);
reportList.Add(dailySummary);
preDay = dayOfYear - 1;
list.Clear();
}
//dailySummary.Date =
dateTimeTemp = dateTimeTemp.AddDays(1);
}
string userFullName;
string PackageName;
using (SPMSEntities db = new SPMSEntities())
{
string userId = User.Identity.GetUserId();
Profile profile = db.Profiles.First(x => x.UserId == userId);
userFullName = profile.FirstName + " " + profile.LastName;
PackageName = db.Packages.First().Name;
}
StiReport report = new StiReport();
report.Load(Server.MapPath("~/Content/Reports/PumpsStatusDailySummary.mrt"));
report.Dictionary.Variables.Add(new StiVariable("Params", "TodayPersianDate", Convertor.ToPersianDate(DateTime.Now)));
report.Dictionary.Variables.Add(new StiVariable("Params", "StartPersianDate", Convertor.ToPersianDate(dateTimeStart)));
report.Dictionary.Variables.Add(new StiVariable("Params", "EndPersianDate", Convertor.ToPersianDate(dateTimeEnd)));
report.Dictionary.Variables.Add(new StiVariable("Params", "UserFullName", userFullName));
report.Dictionary.Variables.Add(new StiVariable("Params", "PackageName", PackageName));
report.RegBusinessObject("Data", reportList);
report.Compile();
return StiMvcViewer.GetReportSnapshotResult(report);
}
catch (Exception e)
{
HelperStoreSqlLog.WriteError(e, "PumpsStatusDailySummarySnapshot");
return View();
}
}
Related
I have an excel file with about 21000 rows . I imported it into a temp Table in my database.
Now I want to do some conversions on my data and then put them into my main table.
When I do SaveChanges() inside a foreach I got the following error:
Microsoft.Data.SqlClient.SqlException: 'New transaction is not allowed because there are other threads running in the session
When I use it after the foreach no error occurs and the table has just 4 records inserted instead of all 21000 records that I expected.
public ActionResult FeedTempdataToMainDB()
{
var L = new Leave();
// var leaves = new List<Leave>();
foreach (var item in db.TempLeaves)
{
L.Pcode = Int32.Parse(item.Cod);
var z = int.Parse(item.LT) - 1;
if (z == 0) L.LT = Leave.LeaveType.Saati;
else L.LT = Leave.LeaveType.Roozane;
var o = int.Parse(item.DLT) - 1;
if (o == 0) L.DLT = Leave.DLType.Estehghaghi;
if (o == 1) L.DLT = Leave.DLType.Estelaji;
else L.DLT = Leave.DLType.Bihoghoogh;
L.LeaveDayStart = item.LeaveDayStart.Old6digToMiladi();
L.LeaveDayEnd = item.LeaveDayEnd.Old6digToMiladi();
L.LeaveTimeStart = StringToHour(item.LeaveTimeStart);
L.LeaveTimeEnd = StringToHour(item.LeaveTimeEnd);
L.LeaveDays = int.Parse(item.LeaveDays);
L.LeaveMinuts = SaatiLengh(item.LeaveMinuts);
L.RegDate = StringToHour(item.RegTime);
L.RegDate = item.RegDate.Old6digToMiladi().Date;
L.RegistrarCode = Int32.Parse(item.RegistrarCode);
L.HijriYear = L.LeaveDayStart.GetHijriYear();
var t = IsOk(item.RegTime);
if (L.DLT == 0 && t == false || L.LT == 0)
{
L.Calculate = false;
L.IsActive = false;
}
else { L.Calculate = true; L.IsActive = true; }
db.Leaves.Add(L);
db.SaveChangesAsync();
}
//db.SaveChanges();
return RedirectToAction("index");
You have a bug in your code. You declared and created L outside of the loop. Each time you add the same L , only with different data. In the end you have list of the same data that was created during the last foreach loop cicle.
try this:
foreach (var item in db.TempLeaves)
{
var z = int.Parse(item.LT) - 1;
var L = new Leave{
Pcode = Int32.Parse(item.Cod),
LeaveTimeStart = StringToHour(item.LeaveTimeStart),
LeaveTimeEnd = StringToHour(item.LeaveTimeEnd),
LeaveDays = int.Parse(item.LeaveDays),
LT = z == 0? Leave.LeaveType.Saati : Leave.LeaveType.Roozane
};
db.Leaves.Add(L);
}
or this
var leaves= new List<Leave>();
foreach (var item in db.TempLeaves)
{
var z = int.Parse(item.LT) - 1;
var L = new Leave{
Pcode = Int32.Parse(item.Cod),
LeaveTimeStart = StringToHour(item.LeaveTimeStart),
LeaveTimeEnd = StringToHour(item.LeaveTimeEnd),
LeaveDays = int.Parse(item.LeaveDays),
LT = z == 0? Leave.LeaveType.Saati : Leave.LeaveType.Roozane
};
leaves.Add(L);
}
if(leaves.Count>0)
{
db.Leaves.AddRange(leaves);
db.SaveChanges();
}
if you want to use async save you have to make async action at first.
The raison every time that foreach execute the savechnages there is a thread that your not note controlling. Since entity framework is managing the savechanges function. You have to execute your savechnages after the foreach or use async function.
here an example for the async:
private static async Task<Student> GetStudent()
{
Student student = null;
using (var context = new SchoolDBEntities())
{
Console.WriteLine("Start GetStudent...");
student = await (context.Students.Where(s => s.StudentID == 1).FirstOrDefaultAsync<Student>());
Console.WriteLine("Finished GetStudent...");
}
return student;
}
*This Code finally worked:
public ActionResult FeedTempdataToMainDB()
{
var leaves = new List<Leave>();
foreach (var item in db.TempLeaves)
{
var L = new Leave();
L.Pcode = Int32.Parse(item.Cod);
var z = int.Parse(item.LT) - 1;
if (z == 0) L.LT = Leave.LeaveType.Saati;
else L.LT = Leave.LeaveType.Roozane;
var o = int.Parse(item.DLT);
if (o == 0) L.DLT = Leave.DLType.Estehghaghi;
if (o == 1) L.DLT = Leave.DLType.Estelaji;
else L.DLT = Leave.DLType.Bihoghoogh;
L.LeaveDayStart = item.LeaveDayStart.Old6digToMiladi();
L.LeaveDayEnd = item.LeaveDayEnd.Old6digToMiladi();
L.LeaveTimeStart = StringToHour(item.LeaveTimeStart);
L.LeaveTimeEnd = StringToHour(item.LeaveTimeEnd);
L.LeaveDays = int.Parse(item.LeaveDays);
L.LeaveMinuts = SaatiLengh(item.LeaveMinuts);
L.RegDate = StringToHour(item.RegTime);
L.RegDate = item.RegDate.Old6digToMiladi().Date;
L.RegistrarCode = Int32.Parse(item.RegistrarCode);
L.HijriYear = L.LeaveDayStart.GetHijriYear();
var t = IsOk(item.RegTime);
if (L.DLT == 0 && t == false || L.LT == 0 && t == false)
{
L.Calculate = false;
L.IsActive = false;
}
else { L.Calculate = true; L.IsActive = true; }
leaves.Add(L);
}
if (leaves.Count > 0)
{
db.Leaves.AddRange(leaves);
db.SaveChanges();
}
return RedirectToAction("index");
}
Excel sheets made by different different clients...that code works when i make but not when user make..is anything problem with excel sheet so , i can tell user make like that way..or i can do anything with my code.
private void MeterUpdateByExcelSheet(HttpPostedFileBase file)
{
List<string> errorMessages = new List<string>();
int siteId = Helpers.SiteHelpers.Functions.GetSiteIdOfLoginUser().Value;
var stream = file.InputStream;
using (var package = new ExcelPackage(stream))
{
//getting number of sheets
var sheets = package.Workbook.Worksheets;
int totalProcessedMeters = 0;
if (sheets.Count > 0)
{
var sheet = sheets.FirstOrDefault();
//getting number of rows
var rows = sheet.Dimension.End.Row;
for (int row = 2; row <= rows; row++)
{
//get data for a row from excel
var meterNo = Convert.ToString(sheet.Cells[row, 1].Value);
int? sanctionLoadMains = (int)Convert.ToDecimal(sheet.Cells[row, 2].Value);
int? sanctionLoadDG = (int)Convert.ToDecimal(sheet.Cells[row, 3].Value);
int? unitArea = (int)Convert.ToDecimal(sheet.Cells[row, 4].Value);
int? creditLimit = (int)Convert.ToDecimal(sheet.Cells[row, 5].Value);
int? sMSWarning = (int)Convert.ToDecimal(sheet.Cells[row, 6].Value);
int? sMSWarning1 = (int)Convert.ToDecimal(sheet.Cells[row, 7].Value);
string date = sheet.Cells[row, 8].Value.ToString();
DateTime billingDate;
if (string.IsNullOrEmpty(date))
{
errorMessages.Add("Date is not given for MeterNo " + meterNo + " at row " + row);
continue;
}
if (!DateTime.TryParseExact(date, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out billingDate))
{
errorMessages.Add("Date format is not correct for MeterNo. " + meterNo + " at row " + row);
continue;
}
if (!string.IsNullOrEmpty(meterNo))
{
meterNo = meterNo.PadLeft(9, '0');
var oldMeter = _meterRepository.GetBySiteIdAndMeterNo(siteId, meterNo);
var newMeter = _meterRepository.GetBySiteIdAndMeterNo(siteId, meterNo);
int wattUnit = 1000;//loads should be multiple of 1000(watt)
int smsWarningUnit = 100;//sms warnings should be multiple of 100
if (newMeter == null)
{
errorMessages.Add("MeterNo. " + meterNo + " does not exist.");
continue;
}
if (sanctionLoadMains.HasValue && sanctionLoadMains >= 500)
{
newMeter.LoadSenctionMain = sanctionLoadMains.Value;
}
if (sanctionLoadDG.HasValue && sanctionLoadDG >= 500)
{
newMeter.LoadSenctionDG = sanctionLoadDG.Value;
}
if (unitArea.HasValue)
{
newMeter.UnitArea = unitArea.Value;
}
if (creditLimit.HasValue)
{
newMeter.CreditLimit = creditLimit.Value;
}
if (sMSWarning.HasValue && sMSWarning >= 100)
{
newMeter.SMSWarningAmount = sMSWarning.Value;
}
if (sMSWarning1.HasValue && sMSWarning1 >= 100)
{
newMeter.SMSWarning1Amount = sMSWarning1.Value;
}
if (billingDate != null)
{
newMeter.BillingDate = billingDate.ToIndiaDateTime();
}
_meterRepository.AddOrUpdate(newMeter);
var meterNotes = Helpers.MeterHelpers.Functions.GetMeterNote(oldMeter, newMeter);
Helpers.MeterHelpers.Functions.AddMeterNotes(meterNo, meterNotes);
totalProcessedMeters++;
}
}
TempData["SuccessMessage"] = totalProcessedMeters + " Meter(s) have been updated successfully";
}
I want to make my code short and simple using linq.
I have a list that contains leaveDates and every leaveDates contain number of leavelist.
Something like this:
{ leaves_date = {07-05-2018 18:30:00}, LeaveList = {System.Collections.Generic.List<TimeClock.Model.LeaveManagementModel>} }
{ leaves_date = {08-05-2018 18:30:00}, LeaveList = {System.Collections.Generic.List<TimeClock.Model.LeaveManagementModel>} }
{ leaves_date = {21-05-2018 18:30:00}, LeaveList = {System.Collections.Generic.List<TimeClock.Model.LeaveManagementModel>} }
leaveList contains UserId, LeaveType, Status fields
Now all I want is to count the number of leavedates per user who's status is 1 and leave type != 3
I have already tried using a for loop, but I want to do it with linq.
Here is my code with the for loop:
for (var i = 0; i < leavesresult.Count; i++) {
for (var a = 0; a < leavesresult[i].LeaveList.Count; a++) {
if (leavesresult[i].LeaveList[a].status == 1.ToString() && leavesresult[i].LeaveList[a].leave_type != 3.ToString()) {
var compair1 = leavesresult[i].LeaveList[a].user_id;
var compair2 = attendancelist.Any(z = >z.user_id == leavesresult[i].LeaveList[a].user_id);
if (attendancelist.Any(z = >z.user_id == leavesresult[i].LeaveList[a].user_id)) {
int index = attendancelist.FindIndex(y = >y.user_id == leavesresult[i].LeaveList[a].user_id);
if (leavesresult[i].LeaveList[a].check_halfday == 1) {
attendancelist[index].days = attendancelist[index].days
}
else {
attendancelist[index].days = attendancelist[index].days + 1;
}
}
else {
if (leavesresult[i].LeaveList[a].check_halfday == 1) {
attendancelist.Add(new AttendanceModel {
user_id = leavesresult[i].LeaveList[a].user_id,
days = 0.5
});
}
else {
attendancelist.Add(new AttendanceModel {
user_id = leavesresult[i].LeaveList[a].user_id,
days = 1
});
}
}
}
}
}
I could give you the query and you would learn nothing. Instead learn how to do this transformation yourself. The trick is to not try to do it all at once. Rather, we make a series of small, obviously correct transformations each one of which gets us closer to our goal.
Start by rewriting the inner for loop as a foreach:
for (var i = 0; i < leavesresult.Count; i++)
{
foreach (var leavelist in leavesresult[i].LeaveList)
{
if (leavelist.status == 1.ToString() && leavelist.leave_type != 3.ToString())
{
var compair1 = leavelist.user_id;
var compair2 = attendancelist.Any(z => z.user_id == leavelist.user_id);
if (attendancelist.Any(z => z.user_id == leavelist.user_id))
{
int index = attendancelist.FindIndex(y => y.user_id == leavelist.user_id);
if (leavelist.check_halfday == 1)
attendancelist[index].days = attendancelist[index].days
else
attendancelist[index].days = attendancelist[index].days + 1;
}
else
{
if (leavelist.check_halfday == 1)
attendancelist.Add(
new AttendanceModel {user_id = leavelist.user_id, days = 0.5});
else
attendancelist.Add(
new AttendanceModel {user_id = leavelist.user_id, days = 1});
}
}
}
}
Already your code is about 100 times easier to read with that change.
Now we notice a few things:
if (leavelist.status == 1.ToString() && leavelist.leave_type != 3.ToString())
That is a crazy way to write this check. Rewrite it into a sensible check.
var compair1 = leavelist.user_id;
var compair2 = attendancelist.Any(z => z.user_id == leavelist.user_id);
Neither of these variables are ever read, and their initializers are useless. Delete the second one. Rename the first one to user_id.
if (leavelist.check_halfday == 1)
attendancelist[index].days = attendancelist[index].days
else
attendancelist[index].days = attendancelist[index].days + 1;
The consequence makes no sense. Rewrite this.
OK, we now have
for (var i = 0; i < leavesresult.Count; i++)
{
foreach (var leavelist in leavesresult[i].LeaveList)
{
if (leavelist.status == "1" && leavelist.leave_type != "3")
{
var user_id= leavelist.user_id;
if (attendancelist.Any(z => z.user_id == leavelist.user_id))
{
int index = attendancelist.FindIndex(y => y.user_id == leavelist.user_id);
if (leavelist.check_halfday != 1)
attendancelist[index].days = attendancelist[index].days + 1;
}
else
{
if (leavelist.check_halfday == 1)
attendancelist.Add(
new AttendanceModel {user_id = leavelist.user_id, days = 0.5});
else
attendancelist.Add(
new AttendanceModel {user_id = leavelist.user_id, days = 1});
}
}
}
}
Use the helper variable throughout:
for (var i = 0; i < leavesresult.Count; i++)
{
foreach (var leavelist in leavesresult[i].LeaveList)
{
if (leavelist.status == "1" && leavelist.leave_type != "3")
{
var user_id = leavelist.user_id;
if (attendancelist.Any(z => z.user_id == user_id))
{
int index = attendancelist.FindIndex(y => y.user_id == user_id);
if (leavelist.check_halfday != 1)
attendancelist[index].days = attendancelist[index].days + 1;
}
else
{
if (leavelist.check_halfday == 1)
attendancelist.Add(
new AttendanceModel {user_id = user_id, days = 0.5});
else
attendancelist.Add(
new AttendanceModel {user_id = user_id, days = 1});
}
}
}
}
We realize that the Any and the FindIndex are doing the same thing. Eliminate one of them:
for (var i = 0; i < leavesresult.Count; i++)
{
foreach (var leavelist in leavesresult[i].LeaveList)
{
if (leavelist.status == "1" && leavelist.leave_type != "3")
{
var user_id = leavelist.user_id;
int index = attendancelist.FindIndex(y => y.user_id == user_id);
if (index != -1)
{
if (leavelist.check_halfday != 1)
attendancelist[index].days = attendancelist[index].days + 1;
}
else
{
if (leavelist.check_halfday == 1)
attendancelist.Add(
new AttendanceModel {user_id = user_id, days = 0.5});
else
attendancelist.Add(
new AttendanceModel {user_id = user_id, days = 1});
}
}
}
}
We notice that we are duplicating code in the final if-else. The only difference is days:
for (var i = 0; i < leavesresult.Count; i++)
{
foreach (var leavelist in leavesresult[i].LeaveList)
{
if (leavelist.status == "1" && leavelist.leave_type != "3")
{
var user_id = leavelist.user_id;
int index = attendancelist.FindIndex(y => y.user_id == user_id);
if (index != -1)
{
if (leavelist.check_halfday != 1)
attendancelist[index].days = attendancelist[index].days + 1;
}
else
{
double days = leavelist.check_halfday == 1 ? 0.5 : 1;
attendancelist.Add(new AttendanceModel {user_id = user_id, days = days});
}
}
}
}
Now your code is 1000x easier to read than it was before. Keep going! Rewrite the outer loop as a foreach:
foreach (var lr in leavesresult)
{
foreach (var leavelist in lr.LeaveList)
{
if (leavelist.status == "1" && leavelist.leave_type != "3")
{
var user_id = leavelist.user_id;
int index = attendancelist.FindIndex(y => y.user_id == user_id);
if (index != -1)
{
if (leavelist.check_halfday != 1)
attendancelist[index].days = attendancelist[index].days + 1;
}
else
{
double days = leavelist.check_halfday == 1 ? 0.5 : 1;
attendancelist.Add(new AttendanceModel {user_id = user_id, days = days});
}
}
}
}
And we notice a couple more things: we can put check_halfday into an explanatory variable, and eliminate days. And we can simplify the increment:
foreach (var lr in leavesresult)
{
foreach (var leavelist in lr.LeaveList)
{
if (leavelist.status == "1" && leavelist.leave_type != "3")
{
var user_id = leavelist.user_id;
int index = attendancelist.FindIndex(y => y.user_id == user_id);
bool halfday= leavelist.check_halfday == 1;
if (index != -1)
{
if (!halfday)
attendancelist[index].days += 1;
}
else
{
attendancelist.Add(new AttendanceModel {user_id = user_id, days = halfday ? 0.5 : 1});
}
}
}
}
Now we begin transforming this to a query. The key thing to understand is that mutations must not go in queries. Mutations only go into loops, never queries. Queries ask questions, they do not perform mutations.
You have a mutation of attendancelist, so that's got to stay in a loop. But we can move all the query logic out of the loop by recognizing that the nested foreach with a test inside the inner loop is equivalent to:
var query = from lr in leaveresult
from ll in lr.LeaveList
where ll.status == "1"
where ll.leave_type != "3"
select ll;
Excellent. Now we can use that in our foreach:
foreach(var ll in query)
{
var index = attendancelist.FindIndex(y => y.user_id == ll.user_id);
var halfday = ll.check_halfday == 1;
if (index != -1)
{
if (!halfday)
attendancelist[index].days += 1;
}
else
{
attendancelist.Add(
new AttendanceModel {user_id = ll.user_id, days = halfday? 0.5 : 1 });
}
}
Now that we have the loop in this extremely simple form, we notice that we can re-order the if to simplify it:
foreach(var ll in query)
{
var index = attendancelist.FindIndex(y => y.user_id == ll.user_id);
var halfday = ll.check_halfday == 1;
if (index == -1)
attendancelist.Add(
new AttendanceModel {user_id = ll.user_id, days = halfday? 0.5 : 1 });
else if (!halfday)
attendancelist[index].days += 1;
}
And we're done. All the computation is done by the query, all the mutations are done by the foreach, as it should be. And your loop body is now a single, extremely clear conditional statement.
This answer is to answer your question, which was how to convert an existing bunch of hard-to-read loops into an easy-to-read query. But it would be better still to write a query that clearly expressed the business logic you're trying to implement, and I don't know what that is. Create your LINQ queries so that they make it easy to understand what is happening at the business level.
In this case what I suspect you are doing is maintaining a per-user count of days, to be updated based on the leave lists. So let's write that!
// dict[user_id] is the accumulated leave.
var dict = new Dictionary<int, double>();
var query = from lr in leaveresult
from ll in lr.LeaveList
where ll.status == "1"
where ll.leave_type != "3"
select ll;
foreach(var ll in query)
{
var halfday = ll.check_halfday == 1;
if (!dict.ContainsKey(ll.user_id))
dict[ll.user_id] = halfday? 0.5 : 1;
else if (!halfday)
dict[ll.user_id] = dict[ll.user_id] + 1;
}
That seems like a nicer way to represent this than a list that you are constantly having to search.
Once we are at this point we can then recognize that what you are really doing is computing a per-user sum! The answer by JamieC shows that you can use the Aggregate helper method to compute a per-user sum.
But again, this is based on the assumption that you have built this whole mechanism to compute that sum. Again: design your code so that it clearly implements the business process in the jargon of that process. If what you're doing is computing that sum, boy, does that ever not show up in your original code. Strive to make it clearer what your code is doing.
This is basically 1 line of linq with a groupby, I'm not sure ill get it spot on with 1 try, but something along the lines of:
var attendancelist = leavesresult
.SelectMany(a => a.LeaveList) // flatten the list
.Where(a => a.status == "1" && a.type != "3") // pick the right items
.GroupBy(a => a.user_id) // group by users
.Select(g => new AttendanceModel(){ // project the model
user_id = g.Key,
days = g.Aggregate(0, (a,b) => a + (b.check_halfday == 1 ? 0.5 : 1))
})
.ToList();
Let me know any issues, and i'll try to fix as necessary.
edit1: Assuming AttendanceModel.days is an int you need to decide what to do as it is calculating a float.
Perhaps something like:
...
days = (int)Math.Ceiling(g.Aggregate(0, (a,b) => a + (b.check_halfday == 1 ? 0.5 : 1)))
...
Not a linq version but used foreach to simplify and make it more readable
var userLeaves = new Dictionary<int, double>();
foreach( var lr in leavesresult)
{
foreach (var leave in lr.LeaveList)
{
if (leave.Status == "1" && leave.LeaveType != "3")
{
var leaveDay = leave.check_halfday ==1 ? 0.5 : 1;
if (userLeaves.ContainsKey(leave.UserID))
userLeaves[leave.UserID] = userLeaves[leave.UserID] + leaveDay;
else
userLeaves.Add(leave.UserID, leaveDay);
}
}
}
I am very new to xml and I am 95% done with my project for work, But when I try and do the last insert into a table it always duplicates my one value.
For example if I have transactions that needs to be inserted into the table and all the transactions are enclosed in a stage node. each stage has transactions.
Now when I insert stage 1 and it has 5 transactions it must take the id of stage 1 then when the insert is done it must then go to stage 2 and then insert 10 transactions.
My issue is when I insert the transactions it will only take the first stage id for all the trans inserts.
Here is my method how I am inserting the transactions
private List<XMLTransaction> GetAllTransForStage(List<XElement> allTransDetails, string path, int curStage, int nxtStage, int journeyEnd, int IDStage, int IDJourney, int IDDuty, int IDModule, string BoardingStages)
{
var end = nxtStage > 0 ? nxtStage : journeyEnd;
var doc = XDocument.Load(path);
List<XElement> StageRersult = GetTranseDetails(doc);
var transForCurrentStage = StageRersult.Where(s => Int32.Parse(s.Attribute("Position").Value.ToString()) > curStage && Int32.Parse(s.Attribute("Position").Value.ToString()) < end).ToList();
var transactions = new List<XMLTransaction>();
string TripBal = "";
string serial = "";
int IDTranse = 0;
int hexClassValue = 0;
int second = 0;
double seconds = 0;
TimeSpan t;
string formatedTime = "";
string date = "";
string issueDate = "";
string issueTime = "";
int stageno = 0;
int HexClasValue = 0;
int Fare = 0;
DataTable dt4 = new DataTable();
dt4.Columns.AddRange(new DataColumn[17] {
new DataColumn("id_Trans",typeof(int)),
new DataColumn("id_Stage", typeof(int)),
new DataColumn("id_Journey", typeof(int)),
new DataColumn("id_Duty",typeof(int)),
new DataColumn("id_Module",typeof(int)),
new DataColumn("int2_BoardingStageID",typeof(int)),
new DataColumn("int2_AlightingStageID",typeof(int)),
new DataColumn("int2_Class",typeof(int)),
new DataColumn("int4_Revenue",typeof(int)),
new DataColumn("int4_NonRevenue",typeof(int)),
new DataColumn("int2_TicketCount",typeof(int)),
new DataColumn("int2_PassCount",typeof(int)),
new DataColumn("int2_Transfers",typeof(int)),
new DataColumn("dat_TransDate",typeof(DateTime)),
new DataColumn("dat_TransTime",typeof(DateTime)),
new DataColumn("str_SerialNumber",typeof(string)),
new DataColumn("int4_TripBal",typeof(int))
});
int batchID = Convert.ToInt32(dtImportDateTime.ToString("yyyyMMdd"));
XDocument xdoc3 = XDocument.Load(path);
XDocument xdoc4 = XDocument.Load(path);
//////////////
string ConString = Settings.Default.ebusimporterConnectionString;
using (SqlConnection con = new SqlConnection(ConString))
{
string sql = "SELECT TOP 1 id_Trans FROM Trans ORDER BY 1 DESC";
SqlCommand cmd = new SqlCommand(sql, con);
try
{
con.Open();
object val = cmd.ExecuteScalar();
if (val != null)
{
IDTranse = Convert.ToInt32(val);
IDTranse = IDTranse + 1;
}
else if (val == null)
{
IDTranse = Convert.ToInt32(val);
IDTranse = IDTranse + 1;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
foreach (var tran in transForCurrentStage)
{
string Hex = tran.Element("TicketType").Value.ToString();
string stageN = tran.Element("StageNo").Value.ToString();
string Issuetime = tran.Element("IssueTime").Value.ToString();
string fares = tran.Element("Fare").Value.ToString();
string Issuedate = tran.Element("IssueDate").Value.ToString();
string TicketSerialNo = tran.Element("TicketSerialNo").Value.ToString();
// string TicketType = item.TicketType.ToString();
hexClassValue = int.Parse(Hex, NumberStyles.HexNumber);
stageno = Int32.Parse(stageN);
HexClasValue = hexClassValue;
second = Int32.Parse(Issuetime);
seconds = second;
t = TimeSpan.FromSeconds(seconds);
formatedTime = string.Format("{0:D2}:{1:D2}:{2:D2}",
t.Hours,
t.Minutes,
t.Seconds);
Fare = Int32.Parse(fares);
string dateLength = Issuedate;
if (dateLength.Length == 5 && HexClasValue == 17 || HexClasValue == 18 || HexClasValue == 33 || HexClasValue == 34 || HexClasValue == 65 || HexClasValue == 66)
{
date = "0" + Issuedate;
issueDate = DateTime.ParseExact(date, "dMMyy", null).ToString("yyyy-MM-d");
issueTime = issueDate + " " + formatedTime;
//Cash
if (HexClasValue == 17 || HexClasValue == 18 || HexClasValue == 33 || HexClasValue == 34 || HexClasValue == 65 || HexClasValue == 66)
{
dt4.Rows.Add(IDTranse, IDStage, IDJourney, IDDuty, IDModule, Convert.ToInt16(BoardingStages), Convert.ToInt16(stageN), Convert.ToInt16(HexClasValue), Fare, 0, 1, 0, 0, Convert.ToDateTime(issueDate), Convert.ToDateTime(issueTime), TicketSerialNo, Convert.ToInt32(0));
IDTranse++;
}
}
if (dateLength.Length == 6 && HexClasValue == 17 || HexClasValue == 18 || HexClasValue == 33 || HexClasValue == 34 || HexClasValue == 65 || HexClasValue == 66)
{
date = Issuedate;
issueDate = DateTime.ParseExact(date, "dMMyy", null).ToString("yyyy-MM-d");
issueTime = issueDate + " " + formatedTime;
//Cash
if (HexClasValue == 17 || HexClasValue == 18 || HexClasValue == 33 || HexClasValue == 34 || HexClasValue == 65 || HexClasValue == 66)
{
dt4.Rows.Add(IDTranse, IDStage, IDJourney, IDDuty, IDModule, Convert.ToInt16(BoardingStages), Convert.ToInt16(stageN), Convert.ToInt16(HexClasValue), Fare, 0, 1, 0, 0, Convert.ToDateTime(issueDate), Convert.ToDateTime(issueTime), TicketSerialNo, Convert.ToInt32(0));
IDTranse++;
}
}
}
string ConnString4 = Settings.Default.ebusimporterConnectionString;
if (HexClasValue == 11000)
{
}
else if (dt4.Rows.Count != 0)
{
using (SqlConnection con4 = new SqlConnection(ConnString4))
{
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(con4))
{
//revenuebal = 0
sqlBulkCopy.DestinationTableName = "dbo.Trans";
sqlBulkCopy.ColumnMappings.Add("id_Trans", "id_Trans");
sqlBulkCopy.ColumnMappings.Add("id_Stage", "id_Stage");
sqlBulkCopy.ColumnMappings.Add("id_Journey", "id_Journey");
sqlBulkCopy.ColumnMappings.Add("id_Duty", "id_Duty");
sqlBulkCopy.ColumnMappings.Add("id_Module", "id_Module");
sqlBulkCopy.ColumnMappings.Add("int2_BoardingStageID", "int2_BoardingStageID");
sqlBulkCopy.ColumnMappings.Add("int2_AlightingStageID", "int2_AlightingStageID");
sqlBulkCopy.ColumnMappings.Add("int2_Class", "int2_Class");
sqlBulkCopy.ColumnMappings.Add("int4_Revenue", "int4_Revenue");
sqlBulkCopy.ColumnMappings.Add("int4_NonRevenue", "int4_NonRevenue");
sqlBulkCopy.ColumnMappings.Add("int2_TicketCount", "int2_TicketCount");
sqlBulkCopy.ColumnMappings.Add("int2_PassCount", "int2_PassCount");
sqlBulkCopy.ColumnMappings.Add("int2_Transfers", "int2_Transfers");
sqlBulkCopy.ColumnMappings.Add("dat_TransDate", "dat_TransDate");
sqlBulkCopy.ColumnMappings.Add("dat_TransTime", "dat_TransTime");
sqlBulkCopy.ColumnMappings.Add("str_SerialNumber", "str_SerialNumber");
sqlBulkCopy.ColumnMappings.Add("int4_TripBal", "int4_TripBal");
con4.Open();
sqlBulkCopy.WriteToServer(dt4);
con4.Close();
}
}
}
LogwriterSuccess("ImportTrans", path);
return transactions;
}
How to clear a cell value of Bounded column in Gridview ?? I perform some calculation and set a int value to a cell(bounded column). Again I recalculate that and try to set in same cell in bounded column time the value not changing so I try to clear the cell value before set a value to it.
private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
// % to amt
object obj = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"]) == DBNull.Value
? 0
: (gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"]));
decimal a = Convert.ToDecimal(obj);
if (a > 0)
{
gridColumn1.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
gridColumn1.UnboundExpression = "[UnitPrice] * ([DiscountPercentage] / 100.0)";
}
// amt to %
object dm = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"]) == DBNull.Value
? 0
: (gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"]));
decimal a1 = Convert.ToDecimal(dm);
if (a1 > 0)
{
gridColumn2.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
gridColumn2.UnboundExpression = "Round(([DiscountAmount] / [UnitPrice]) * 100.0, 2)";
}
}
private void gridView1_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
// % to amt
object obj = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"]) == DBNull.Value
? 0
: (gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"]));
decimal a = Convert.ToDecimal(obj);
if (a > 0)
{
object obj2 = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["gridColumn1"]);
int aa = Convert.ToInt32(obj2);
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"], aa);
}
// amt to %
object dm = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"]) == DBNull.Value
? 0
: (gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"]));
decimal a1 = Convert.ToDecimal(dm);
if (a1 > 0)
{
object obj3 = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["gridColumn2"]);
int aa2 = Convert.ToInt32(obj3);
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"], aa2);
}
}
Thanks in advance.
Finally found solution to solve this problem.
private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
var row = gridView1.GetFocusedDataRow();
object obj1 = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"]) == DBNull.Value
? 0
: (gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountPercentage"]));
int inte1 = Convert.ToInt32(obj1);
object obj2 = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"]) == DBNull.Value
? 0
: (gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["DiscountAmount"]));
int inte2 = Convert.ToInt32(obj2);
// Calculating the dicsount %
if (e.Column == colDiscountAmount)
{
if (inte2 == 0)
{
return;
}
else
{
var productPrice = Convert.ToDecimal(row["UnitPrice"]);
var quan = Convert.ToDecimal(row["Quantity"]);
var discountAmout = Convert.ToDecimal(row["DiscountAmount"]);
var temp = (discountAmout * 100) / (productPrice * quan);
row["DiscountPercentage"] = temp.ToString("n2");
}
}
// Calculating the discount amount
if (e.Column == colDiscountPercentage)
{
if (inte1 == 0)
{
return;
}
else
{
var productPrice = Convert.ToDecimal(row["UnitPrice"]);
var quan = Convert.ToDecimal(row["Quantity"]);
var discountPercent = Convert.ToDecimal(row["DiscountPercentage"]);
var temp1 = (productPrice * quan) * (discountPercent / 100);
row["DiscountAmount"] = temp1.ToString("n2");
}
}
}