I am trying to change date to all workouts in the list, the other properties are working fine, its only when I change Date i get problem. I have tried different trouble shooting, but none have worked. I have tried with using updatedWorkout.Date as workoutStart = out of range. If I use old.Date, then, how can I add the new date with 7days a part ?
Maybe there is a better way to do this?
Here's my method:
private int UpdateForAllWorkouts(IWorkoutCommand updatedWorkout)
{
try
{ // get schedule
var schedule = _scheduleRepository.GetIncludeWorkouts(updatedWorkout.ScheduleId);
// get workouts within the schedule by schedule id
var workout = schedule.Workouts.FirstOrDefault(w => w.Id == updatedWorkout.Id);
for (var workoutStart = workout.Date; workoutStart <= schedule.ToDate; workoutStart = workoutStart.AddDays(7))
{
// get specdfic workout by workout id and start time
var old = schedule.Workouts.Single(w => w.Date == workoutStart && w.StartTime == workout.StartTime);
var tmp = new Model.Workout
{
Id = old.Id,
CourseId = updatedWorkout.CourseId,
InstructorId = updatedWorkout.InstructorId,
Date = //<---problem
StartTime = updatedWorkout.StartTime,
EndTime = updatedWorkout.EndTime,
ScheduleId = updatedWorkout.ScheduleId,
WeekOffSet = updatedWorkout.WeekOffSet.Days
};
}
return updatedWorkout.Id;
}
catch (Exception ex)
{
throw new Exception("");
}
}
thx for helping!
I think you can use a loop for 7.
like this :
var workoutStart = workout.Date;
while(true){
if(workoutStart <= schedule.ToDate){
// Do something
}else{
break;
}
workoutStart = workoutStart.AddDays(7);
}
Please consider to check the value of our DateTime properties.Their values could be less than your SQL server allow for datetime field.
What is the Date value of updatedWorkOut object before you assign "tmp" object ?
Is your "old" object null or what is the value of date ?
your code seems to be ok. the problem underlies the value of DateTime properties and fields.
Related
I am building a website that does has a chat component to it. The code below receives from a stored procedure a list of messages with a lots of different paramaters. 1 of those is if a message is in reply to another, and if that is the case, duplicate the message that is being replied to over the message answer. If the message that was being replied to was also an answer to a previous message do the same ect. Now my issue is that I have not been able to figure out how to automate this part of the code without nesting if into one another until a point where I hope users won't reply in the same chain anymore.
To rephrase it, I go in a list in inverse order and check if the ReplyingTo is not null.
I then copy the row that has the same ID and ReplyingTo 1 row higher than the current row.
I then confirm that this new row has a ReplyingTo
If it does I copy that object 2 row higher than the current one.
and I would continue this way until I reached a certain point that the users would not reach.
If anyone got an idea on how to proceed I would be highly gracious. I have put an example of the type of data that would be given to this function below.
for (int i = publicChatCountList.Count-1 ; i > -1; i--)
{
if (publicChatCountList[i].ReplyingTo.HasValue)
{
Chat_Dto chatItem = new Chat_Dto();
long? ReplyingToId = publicChatCountList[i].ReplyingTo;
chatItem = publicChatCountList.Find(x => x.Id == ReplyingToId);
publicChatCountList.Insert(i+1, new Chat_Dto() {Text = chatItem.Text, IsPublic = chatItem.IsPublic, IsApproved = chatItem.IsApproved, ReplyingTo = chatItem.ReplyingTo });
publicChatCountList[i+1].Duplicate = true;
if (chatItem.ReplyingTo.HasValue)
{
Chat_Dto chatItem2 = new Chat_Dto();
long? ReplyingToId2 = chatItem.ReplyingTo;
chatItem2 = publicChatCountList.Find(x => x.Id == ReplyingToId2);
publicChatCountList.Insert(i + 2, new Chat_Dto() { Text = chatItem2.Text, IsPublic = chatItem2.IsPublic, IsApproved = chatItem2.IsApproved, ReplyingTo = chatItem2.ReplyingTo });
publicChatCountList[i + 2].Duplicate = true;
}
}
}
If I understood you correctly maybe running something like this to recursively get all replies would work:
private void Replies(Chat_Dto_List publicChatCountList,int i)
{
if (publicChatCountList[i].ReplyingTo.HasValue)
{
Chat_Dto chatItem = new Chat_Dto();
long? ReplyingToId = publicChatCountList[i].ReplyingTo;
chatItem = publicChatCountList.Find(x => x.Id == ReplyingToId);
publicChatCountList.Insert(i + 1, new Chat_Dto() { Text = chatItem.Text, IsPublic = chatItem.IsPublic, IsApproved = chatItem.IsApproved, ReplyingTo = chatItem.ReplyingTo });
publicChatCountList[i + 1].Duplicate = true;
if (chatItem.ReplyingTo.HasValue)
{
Replies(publicChatCountList, publicChatCountList.FindIndex(x => x.Id == chatItem.ReplyingTo))
}
}
}
I currently have a piece of code to remove or add dates on a calendar if the date entered is already in the table in my database:
foreach (DateTime date in dates)
{
var dateExists = myDBContext.CalendarDates.Where(x => x.CalendarTypeId == type && x.DateDue == date).FirstOrDefault();
if(dateExists != null)
{
myDBContext.CalendaDates.Remove(dateExists);
}
else
{
CalendarDate newDate = new CalendarDate
{
CalendarTypeId = type,
Date = date,
};
myDBContext.CalendarDates.Add(newDate);
}
}
I would like to do validation before I call SaveChanges() to ensure that only one date can be entered for each month and year. Although when I call my CalendarDates DBSet from my context, it doesn't seem to be updated to include and disregard the new and removed dates:
var dates = myDBContext.CalendarDates.Select(x=> x.Date).ToList();
var uniqueDatesPerMonth = dates.Select(x => new DateTime(x.Year, x.Month, 1)).Distinct().ToList(); // This should include dates that have been added or removed as per the above code
if(dates.Count() != uniqueDatesPerMonth.Count())
{
return false;
} else {
myDBContext.SaveChanges();
}
Is it possible to get the DBSet of the updated table before SaveChanges() is called?
Ended up discovering about the change tracker that store entities to add and remove entities. I ended up using it to modify my list based on what would be added or removed to the context. It now works as expected:
var changeTracker = myDBContext.ChangeTracker.Entries().ToList();
var dates = myDBContext.CalendarDates.Where(x => x.CalendarTypeId == type).ToList();
foreach(var entity in changeTracker)
{
var addRemoveDate = (CalendarDate)entity.Entity;
if(addRemoveDate.Id > 0)
{
timeAllocationDates.RemoveAll(x => x.Id == addRemoveDate.Id);
}
else
{
timeAllocationDates.Add(addRemoveDate);
}
}
var uniqueDatesPerMonth = dates.Select(x => new DateTime(x.Date.Year, x.Date.Month, 1)).Distinct().ToList();
if (dates.Count() != uniqueDatesPerMonth.Count())
{
return false;
}
else
{
myDBContext.SaveChanges();
}
Most of the time I retrieve multiple records so I would end up doing this
var rpmuser = new List<rpm_scrty_rpm_usr>();
I have my List collection of properties from poco
So I typically use select new in my Linq statement
Then I use a foreach and loop over the records in which the List would get model.Add(new instance in each loop)
However , do I really need to be doing all this looping to populate?
Bigger question when i have a single record should I be needing to even do a loop at all?
public bool UpdateAllUsers(string user, string hash, string salt)
{
bool status = false;
var rpmuser = new rpm_scrty_rpm_usr();
var query = (from t in db.rpm_usr
.Where(z => z.usr_id == "MillXZ")
select new
{
t.usr_id,
t.usr_lnm,
t.usr_pwd,
t.usr_fnm,
t.salt,
t.inact_ind,
t.lst_accs_dtm,
t.lst_pwd_chg_dtm,
t.tel,
t.wwid,
t.email_id,
t.dflt_ste_id,
t.apprvr_wwid,
t.chg_dtm,
t.chg_usr_id,
t.cre_dtm,
t.cre_usr_id,
});
foreach(var s in query)
{
rpmuser.wwid = s.wwid;
rpmuser.usr_pwd = s.usr_pwd;
rpmuser.usr_lnm = s.usr_lnm;
rpmuser.usr_id = s.usr_id;
rpmuser.usr_fnm = s.usr_fnm;
rpmuser.tel = s.tel;
rpmuser.salt = s.salt;
rpmuser.lst_pwd_chg_dtm = rpmuser.lst_pwd_chg_dtm;
rpmuser.lst_accs_dtm = s.lst_accs_dtm;
rpmuser.inact_ind = s.inact_ind;
rpmuser.email_id = s.email_id;
rpmuser.apprvr_wwid = s.apprvr_wwid;
rpmuser.chg_dtm = s.chg_dtm;
rpmuser.chg_usr_id = s.chg_usr_id;
rpmuser.cre_usr_id = s.cre_usr_id;
rpmuser.dflt_ste_id = s.dflt_ste_id;
rpmuser.cre_dtm = s.cre_dtm;
}
DateTime dateTime = DateTime.Now;
try
{
rpmuser = db.rpm_usr.Find(rpmuser.usr_id);
rpmuser.usr_pwd = hash;
rpmuser.salt = salt;
db.SaveChanges();
status = true;
}
catch (Exception ex)
{
status = false;
}
return status;
}
I am not exactly sure what you want. Your method says Update All, but only seems to be attempting to update one record. So why don't you just do this?
try
{
var rpmuser = db.rpm_usr.Single(z => z.usr_id == "MillXZ");
rpmuser.usr_pwd = hash;
rpmuser.salt = salt;
db.SaveChanges();
status = true;
}
catch (Exception ex)
{
status = false;
}
You have a lot of redundant declarations unless I am missing something. In the case of the list you will do something like this:
var query = db.rpm_usr.Where(z => z.usr_id == "...some string...");
foreach(var item in query)
{
rpmuser.usr_pwd = ...some value...;
rpmuser.salt = ...some value...;
}
db.SaveChanges();
I can't stress this enough, Murdock's answer is absolutely the right way to fix the code you've shown. You are writing way too much code for what you're trying to accomplish.
However, to answer your question about whether you need to loop in other situations, you can get away from having to loop by doing the projection into a new type as part of your LINQ-to-Entities query. The looping still happens, you just don't see it.
var query = db.rpm_usr
.Where(z => z.usr_id == "MillXZ")
.AsEnumerable()
.Select(z => new rpm_scrty_rpm_usr()
{
usr_id = z.usr_id,
usr_lnm = z.usr_lnm,
// etc...
});
You would then finish the query off with a .Single(), .SingleOrDefault(), or .ToList() depending on whether you expected exactly one, one or zero, or a list. For example, in this case if you might find one or zero users with the name "MillXZ" you would write the following.
var query = db.rpm_usr
.Where(z => z.usr_id == "MillXZ")
.AsEnumerable()
.Select(z => new rpm_scrty_rpm_usr()
{
usr_id = z.usr_id,
usr_lnm = z.usr_lnm,
// etc...
})
.SingleOrDefault();
I have been working on a website and for the first time started using Entity Framework 6. The application is MVC4, C#.
The issue I am having is that EF not always pulls data from the table. For example I will load a page and get an empty result. But if I refresh the page then the data from database will be shown. If I refresh again it goes empty again.
Basically, it's been pulling data every second time (and been very consistent in this behaviour).
I'm really at lost, I even tried to pull data from view instead of the table, but the behaviour stayed consistent.
Here is the relevant code from my application
#region returns list of new files uploaded in the last 24 hours
[HttpPost]
[InitializeSimpleMembership]
public ActionResult LastUploadedFiles()
{
var path = Server.MapPath("~/" + this.uploadPath + "/");
FileListModel filesList = new FileListModel();
using (CCGFileShareEntities db = new CCGFileShareEntities())
{
db.Configuration.AutoDetectChangesEnabled = false;
db.Configuration.ValidateOnSaveEnabled = false;
DateTime daydiff = DateTime.Now.AddHours(-24);
filesList.files = (from r in db.viewFileUploads
where r.file_upload_date >= daydiff && r.file_deleted == 0
//orderby r.file_upload_date descending
select new FileModels()
{
id = r.id,
fileName = r.file_name,
file_description = (r.file_description == null ? "" : r.file_description),
upload_extention = r.upload_extention,
upload_folder = r.upload_folder,
file_upload_date = r.file_upload_date,
upload_owner_id = r.upload_owner_id.ToString(),
file_size = r.file_size.ToString(),
description_is_visible = false
}).ToList();
//get owner and convert date
FileHelpers fhelpers = new FileHelpers();
for (int i = 0; i < filesList.files.Count(); i++)
{
filesList.files[i].file_upload_date_string = filesList.files[i].file_upload_date.ToString("MMM dd, yyyy");
int ownerID = int.Parse(filesList.files[i].upload_owner_id);
filesList.files[i].fileOnwerName = fhelpers.getUserName(ownerID);
}
filesList.currentUserID = WebSecurity.GetUserId(User.Identity.Name);
//public string upload_owner_id { get; set; }
}
return Json(filesList);
}
I've no idea why it doesn't pull data every single time as it supposed to do.
I'm really at loss and would appreciate your help.
Thanks in advance,
I am getting the error
"An item with the same key has already been added"
in production randomly.if i execute the below code in local i am not getting the issue.please suggestion needed to solve this issue.
//check for whether Midas.DAB is Enabled in the App.Config File
if (ProcessMidasDab)
{
var dvFilteredMidasDabDetails = new DataView(dtMidasDabandSurgDetails) {
RowFilter = "not (LastReceivedOnForDAB is null)" };
dtCmMidasDabAlerts.Columns.Add("ClientID");
dtCmMidasDabAlerts.Columns.Add("LastFileReceivedDate");
dtCmMidasDabAlerts.Columns.Add("SendingSystem");
//Get the Cut-off time for Midas.DAB from the App.config.
var timeStamp = ConfigurationManager.AppSettings["TimeLapseforMidasDABinhrs"];
//Logic to check the Feed for Midas.DAB
foreach (DataRowView dv in dvFilteredMidasDabDetails)
{
midasDabClientList.Add(Convert.ToInt32(dv["ClientID"]));
var timeDifference =
(DateTime.Now - Convert.ToDateTime(dv["LastReceivedOnForDAB"])).TotalHours;
if (timeDifference > Convert.ToDouble(timeStamp))
{
var drNewRow = dtCmMidasDabAlerts.NewRow();
drNewRow["ClientID"] = dv["ClientID"];
drNewRow["LastFileReceivedDate"] = dv["LastReceivedOnForDAB"];
drNewRow["SendingSystem"] = "Midas.DAB";
dtCmMidasDabAlerts.Rows.Add(drNewRow);
}
}
dabclients = midasDabClientList;
}
You have two time assign this
drNewRow["Clientid"] = 12;
drNewRow["ClientID"] = dv["ClientID"];
Please remove this one
drNewRow["Clientid"] = 12;
and also you have two time assigned this
dtCmMidasDabAlerts.Columns.Add("ClientID");