DateTime manipulation inside Linq to entities query - entity-framework-4

running this code:
public bool CheckTime(DateTime date, int UserID, int TotalTimeMin)
{
using (var context = new myDB())
{
var assginments = from c in context.Assignments.Where(x=>(x.AssignmentDateTime < date && x.AssignmentDateTime.Value.AddMinutes(TotalTimeMin) > date) ||
(x.AssignmentDateTime < date.AddMinutes(TotalTimeMin))) select c;
if(assginments != null) return false;
else return true;
}
}
I get this error.
LINQ to Entities does not recognize the method 'System.DateTime AddMinutes(Double)' method, and this method cannot be translated into a store expression.
TotalTimeMin is int. I am not sure what cause this:
AssignmentDateTime is DateTime? and maybe this is the problem ?

Use EntityFunctions.AddMinutes (requires EF 4):
public bool CheckTime(DateTime date, int UserID, int TotalTimeMin)
{
using (var context = new myDB())
{
var assginments = context.Assignments
.Where(x=>(x.AssignmentDateTime < date
&& EntityFunctions.AddMinutes(x.AssignmentDateTime,TotalTimeMin) > date)
|| (x.AssignmentDateTime < date.AddMinutes(TotalTimeMin)));
if(assginments != null) return false;
else return true;
}
}
Note that assignments will never be null (but it might be empty -- test assignments.Any()).

Related

am working on updating a single attribute in the User Model which is the balance attribute,

how I can update a single value for an already existing row in the db by only having a parameters that I want to add it to this attribute
here is my code for a trivial way but didnt work
public bool BuyBook(int BookId, int UserId, int BookPrice){
using (var ctx = new OnlineBooksEntities())
{
User updatedCustomer = (from c in ctx.Users
where c.UserId == UserId
select c).FirstOrDefault();
updatedCustomer.Balance = BookPrice;
ctx.SaveChanges();
}
this.DeleteBook(BookId);
return true;
}
Add an sql query to the method solves the update aim
public bool BuyBook(int BookId, int UserId, int BookPrice)
{
try
{
using (var ctx = new OnlineBooksEntities())
{
User user = ctx.Users.Where(x => x.UserId == UserId).FirstOrDefault();
BookPrice = (int)user.Balance + BookPrice;
int noOfRowUpdated =
ctx.Database.ExecuteSqlCommand("Update Users set Balance = "+BookPrice+ " where UserId ="+UserId);
}
Updating basically means changing an existing row's value. Since you mentioned EF, you can do this by retrieving the object, changing its value, and saving it back. Thus you can do something like this:
using (var db = new MyContextDB())
{
var result = db.Books.SingleOrDefault(b => b.BookPrice == bookPrice);
if (result != null)
{
result.SomeValue = "Your new value here";
db.SaveChanges();
}
}

How to unit test a public void method in C# MVC

I have a public void method, SaveCover2AData(). How can I create a unit test for this type of method?
This is my public method, I am passing a model object as a parameter in this method.
Now I want to create unit test for this method:
public void SaveCover2AData(CASTabCover2a t2a)
{
CASCreateViewModel obj = (CASCreateViewModel)Session["CASQuote"];
t2a.Quote_Exposures = t2a.Quote_Exposures.Where(x => x.Exposure != null || x.ExposurePL != null).ToList();
t2a.Quote_Jurisdictions = t2a.Quote_Jurisdictions.Where(x => x.Jurisdiction_Name != null || x.Country_NamePL != null).ToList();
t2a.Quote_LimtOfIndemnitys = t2a.Quote_LimtOfIndemnitys.Where(x => x.Indemnity != null || x.IndemnityPL != null || x.LimitOfIndemnity_Currency != null).ToList();
t2a.Quote_SubLimitOfIndemnitys = t2a.Quote_SubLimitOfIndemnitys.Where(x => x.Indemnity != null || x.IndemnityPL != null || x.SubLimitOfIndemnity_Currency != null).ToList();
obj.TabCover2a = t2a;
Session.Add("CASQuote", obj);
ViewBag.Quote_Status_ID = JsonConvert.SerializeObject(obj.Quote_Status_ID);
}
The test method I've attempted so far is:
[TestMethod]
public void CASSaveCover2AData()
{
builder.InitializeController(controller);
var CASTabCover2a = new CASTabCover2a();
controller.SaveCover2AData(CASTabCover2a);
Assert.IsTrue(true);
}
When I am debugging this test case I am getting this error:
An exception of type 'System.NullReferenceException' occurred
First, your variable name is invalid here
var CASTabCover2a = new CASTabCover2a();
Second, void methods affects the database, inserts data or deletes data. In this point before run your void method get the counts of total rows in related table. If row count changed, your method works correctly.
If you insert data, total counts of row must be increased. If deleted vice versa.
public void MyTestMethod()
{
var total = db.Cars.Count();
var car = new Car();
db.Save(car);
var total2 = db.Cars.Count();
Assert.True(total2 > total);
}

Something is slow in my code, any suggestions?

I have a list of big records and I need to loop through each record, add some filter and calculation and add it to my another list. I think doing one by one is affecting the performance because it's taking like 12s to show 900 records.
I am unable to identify why it's taking too long. I used my chrome developer tool to identify where it's slow. Then I came to find out loading taking 0.2s, scripting taking 3s, rendering taking 3s, idle is 3s and others are two seconds.
Maybe I am using Entity Framework and DataTables is making it slow. Or maybe something wrong is with my query. Following is my code:
public ActionResult Index(int id, string language)
{
var All_Employees = from employee in db.Employees
.Include(x => x.Country).Include(x => x.Status)
where enployee.GenderId == id
select employee ;
var List = new List<EmployeeListViewModel>();
foreach(var Record in All_Employees.ToList()
.OrderByDescending(x=> ParseDate(x.JoiningDate)))
{
EmployeeListViewModel item = new EmployeeListViewModel();
item.Id = Record.Id;
item.Code = Record.Code;
if(Record.CountryId != null)
{
if(language == "en")
{
item.Country = Record.Country.NameE;
}
else
{
item.Country = Record.Country.NameA;
}
}
item.Date = Record.JoiningDate;
int WorkingDays = 0;
if(Record.JoiningDate != null)
{
DateTime Joining= Convert.ToDateTime(ParseDate(Record.Record.JoiningDate));
TimeSpan t = DateTime.Now.Date - Joining;
int Days = int.Parse(t.TotalDays.ToString());
if (Days > 0)
{
WorkingDays = Days;
}
}
item.Days = WorkingDays.ToString();
if (Record.StatusId != null)
{
if (language == "en")
{
item.Status = Record.Status.NameE;
}
else
{
item.Status = Record.Status.NameE;
}
}
List.Add(item);
}
return View(List);
}
Another reason could be I am converting my date:
private static DateTime? ParseDate(string dateString)
{
if(dateString != null)
{
return DateTime.ParseExact(dateString, "dd-MM-yyyy", CultureInfo.GetCultureInfo("en-US"), DateTimeStyles.None);
}
else
{
return null;
}
}
I don't want to make date filed as DateTime in my database, due to some reasons.
What's the best way to improve performance in my current situation?
Too much casting is used here in your code and list is created twice. One way you can do code like below.
List<EmployeeListViewModel> lstData = EmployeeListViewModel.ToList();
for(int i = 0; i < lstData.Count; i++)
{
//Put logic here for required changes like Language and Date.
if(lstData[i].CountryId != null)
{
if(language == "en")
lstData[i].Country = lstData[i].Country.NameE;
else
lstData[i].Country = lstData[i].Country.NameA;
}
}
Try to reduce casting specially for string and date-time. Below is example.
int Days = int.Parse(t.TotalDays.ToString());
In above line t.TotalDays is always int type, no need to cast to string and int again.

EF modify entity in a function

// Inside an action result
tp = dbContext.tp.Single(x => ...);
foreach (Sample sample in tp.samples)
{
if (sample.SampleStatusId == 1)
changeSamplestatus(sample, 2, now); //change samples to on hold
}
dbContext.SaveChanges();
public void changeSamplestatus(Sample sample, int sampleStatus, DateTime now)
{
sample.SampleHistory.Add(new SampleHistory
{
OldStatus = sample.SampleStatusId,
NewStatus = sampleStatus,
});
sample.SampleStatusId = sampleStatus;
}
I have an entity (sample) that I would like to change it status.
I am calling a function to do so, but the entity doesn't get modified (but it is creating a new row in history table with the correct FK).
It doesn't throw any errors when SaveChanges is called. It just doesn't modify the entity.
You can try:
//INSIDE AN ACTION RESULT
var tp = dbContext.tp.SingleOrDefault(x => ...);
if (tp != null)
{
foreach (Sample sample in tp.samples)
{
if (sample.SampleStatusId == 1)
changeSamplestatus(sample, 2, DateTime.Now);
}
int flag = dbContext.SaveChanges();
if (flag > 0)
{
// update successful
}
}
public void changeSamplestatus(Sample sample, int sampleStatus, DateTime now)
{
//sample.SampleHistory.Add(new SampleHistory
//{
// OldStatus = sample.SampleStatusId,
// NewStatus = sampleStatus,
//});
sample.SampleStatusId = sampleStatus;
}
Don't use Single for this case, because it would throw exception if no result was found or there were more than 1 result. Use SingleOrDefault or FirstOrDefault instead.
You can try this . I hope thiw will work . The Idea is to get the history records first in the context and then update the propterties and set state to mofifed . Please try I didnt tested it but it should work.
public void changeSamplestatus(Sample sample, int sampleStatus, DateTime now)
{
var historyRecordToUpdate = db.SampleHistory.FirstOrDefault(h=>h.id == sampleHistoryId )
if(historyRecordToUpdate !=null )
{
db.Entry(sample).State= EntityState.Modified;
sample.SampleStatusId = sampleStatus;
}
}

Reflection + Entity Framework to update data in MVC app

I've got a complex form on a page that is bound to a POCO representing a rather complex entity. One of the requirements is that, on blur, I update the database.
I'm currently passing the property (as key), value, and CampaignId via ajax. The key might look something like: Campaign.FanSettings.SocialSharing.FacebookLinkText.
I am using the code below, and getting "close". My final propertyToSet is the FacebookLinkText is not being set, because my object source is of type Entities.Campaign, while my object value is simply a string. I understand these need to be the same type, but I don't understand how to do that. Two questions:
How do I modify the code below to be able to execute the propertyToSet.SetValue method
Since I'm casting this to an object, I don't see how this would actually update my entity, so when I call SaveChanges it updates appropriately. What am I missing?
Thanks!
Code:
public void UpdateCampaign(int id, string key, string value)
{
using (var context = new BetaEntities())
{
var camp = context.Campaigns.Where(e => e.Id == id).Single();
SetProperty(camp, key,value);
}
}
public void SetProperty(object source, string property, object value)
{
string[] bits = property.Split('.');
for (int i = 0; i < bits.Length - 1; i++)
{
PropertyInfo prop = source.GetType().GetProperty(bits[i]);
source = prop.GetValue(source, null);
}
PropertyInfo propertyToSet = null;
if (source is IEnumerable)
{
foreach (object o in (source as IEnumerable))
{
propertyToSet = o.GetType().GetProperty(bits[bits.Length - 1]);
break;
}
}
else
{
propertyToSet = source.GetType().GetProperty(bits[bits.Length - 1]);
}
propertyToSet.SetValue(source, value, null);
}
Solved.
public void UpdateCampaign(int id, string key, string value)
{
using (var context = new BetaEntities())
{
var camp = context.Campaigns.Where(e => e.Id == id).Single();
SetProperty(camp, key, value);
context.SaveChanges()
}
}
public void SetProperty(object source, string property, object value)
{
string[] bits = property.Split('.');
for (int i = 0; i < bits.Length - 1; i++)
{
PropertyInfo prop = source.GetType().GetProperty(bits[i]);
source = prop.GetValue(source, null);
}
PropertyInfo propertyToSet = null;
if (source is IEnumerable)
{
foreach (object o in (source as IEnumerable))
{
propertyToSet = o.GetType().GetProperty(bits[bits.Length - 1]);
propertyToSet.SetValue(o, value,null);
break;
}
}
else
{
propertyToSet = source.GetType().GetProperty(bits[bits.Length - 1]);
propertyToSet.SetValue(source, value, null);
}
}

Resources