Subtract dates in Linq EF6 - linq

Hello i have big problem with Subtract at Linq,EF6.
I have date where repair should be finieshed. I woluld like to count how many days left.
At ViewModel I have:
public TimeSpan TimeToLeft{get;set;}
At repair controler i do sth like this:
var repairsToDo = from r in db.Repairs
join c in db.Car on r.Car equals c.ID_Car
join m in db.Models on c.ID_Modelu equals m.ID_Modelu
join b in db.Brand on m.ID_Brand equals b.Brand
where r.Data_Zakonczenia>=DateTime.Today
select new RepairsToDo { TimeToLeft=(r.EndDate-DateTime.Today) };
View:
<table class="ShowDataTab">
<tr>
<th>Repair Number</th>
<th>Car</th>
<th>Name</th>
<th>Desc</th>
<th>Time to left</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>#item.FixNumber</td>
<td>#item.Brand#item.Model</td>
<td>#item.FixName</td>
<td>#item.FixDesc</td>
<td>#item.TimeToLeft</td>
</tr>
}
</table>
And i got error like this:
dbarithmeticexpression arguments must have a numeric common type
How can i Fix it?
EDIT1:
Controler:
var today = DateTime.Today;
var repairsToDo = from r in db.Repair
join c in db.Car on r.Car equals c.ID_Car
join m in db.Models on c.ID_Model equals m.ID_Model
join b in db.Brand on m.ID_Brand equals b.ID_Brand
where r.EndTime>=DateTime.Today
select new { ... EndTime=r.EndTime };
var model = repairsToDo.AsEnumerable().Select(raw => new RepairsToDo {... TimeLeft= raw.EndTime- today });
return View(model);
Error:
The model item passed into the dictionary is of type 'System.Linq.Enumerable+WhereSelectEnumerableIterator`2[<>f__AnonymousType1a`7[System.Int32,System.String,System.String,System.String,System.String,System.String,System.DateTime],Praca_Inzynierska.Models.RepairsToDo]', but this dictionary requires a model item of type 'System.Linq.IQueryable`1[Praca_Inzynierska.Models.RepairsToDo]'.
enter code here

It's probably simplest to just fetch the data from EF, and then perform the arithmetic locally:
var today = DateTime.Today;
var rawData = from r in db.Repairs
join c in db.Car on r.Car equals c.ID_Car
join m in db.Models on c.ID_Modelu equals m.ID_Modelu
join b in db.Brand on m.ID_Brand equals b.Brand
where r.Data_Zakonczenia >= DateTime.Today
select new { ..., r.EndDate };
var model = rawData.AsEnumerable() // Perform the select locally
.Select(raw => new RepairsToDo {
... // other properties
TimeToLeft = raw.EndDate - today
});
Note that I've fetched DateTime.Today once, rather than doing it multiple times - that way you'll get a consistent result, even if this query is performed around midnight.
I'd also recommend renaming TimeToLeft as TimeLeft or RemainingTime.

Try:
TimeToLeft = SqlFunctions.DateDiff("DAY", r.EndDate, DateTime.Now)
Change DAY for whatever unit you want. See http://msdn.microsoft.com/en-us/library/dd487052(v=vs.110).aspx and http://msdn.microsoft.com/en-us/library/ms189794.aspx.

With EF6 use
System.Data.Entity.DbFunctions.DiffHours(time1,time2).Value
for example:
using System.Data.Entity;
...
entity.tableData.Select(m => new
{
m.Key,
horasTotales = m.Sum(h => DbFunctions.DiffHours(h.fecha_fin, h.fecha_inicio).Value)
})

Related

How does one use .ToList() Inside of a Linq Query?

I've got a class that contains a list item. I would like for a linq query to populate the class, including this list. Here is my query:
var query = from c in context.Cars
select new CarListItem()
{
ID = c.ID,
Make = c.Make,
AvailableColors = context.CarColors.Where(u => u.CarID == c.ID).ToList()
};
Basically, I want to get a list of all of the cars, including a list of the available colors for each respective car.
The problem is that the inclusion of .ToList() within the query results in an error: An error occurred:
LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[CarSystem.Models.CarColors] ToList[CarColors](System.Collections.Generic.IEnumerable`1[CarSystem.Models.CarColors])' method, and this method cannot be translated into a store expression.
At this point, I don't know whether I am just using wrong syntax within the Linq query (should I use something other than .ToList()?) or if maybe the architecture of the models is wrong.
You can't. EF tries to translate ToList() to SQL and doesn't know how.
You could project to another type, then call ToList():
var query = (from c in context.Cars
select new
{
ID = c.ID,
Make = c.Make,
AvailableColors = context.CarColors.Where(u => u.CarID == c.ID)
}).ToList()
.Select(c => new CarListItem()
{
ID = c.ID,
Make = c.Make,
AvailableColors = c.AvailableColors.ToList()
});
or change the type of CarListItem.AvailableColors to IEnumerable<CarColor>:
var query = from c in context.Cars
select new CarListItem()
{
ID = c.ID,
Make = c.Make,
AvailableColors = context.CarColors.Where(u => u.CarID == c.ID)
};

showing multiple rows from database in datagridview using entity framework

I am trying to show multiple records from database in datagridview but I'm having only a single record all the time.
2 tables are involved in this query, from 1st table I acquire all the id's those fulfill the condition and from 2nd table I am getting the user information.
1st table is tblUsers_Roles and 2nd is tblUsers.
These tables have primary/foriegn key relationship.
Here is my code:
IEnumerable<tblUsers_Role> id = db.tblUsers_Role.Where(a => a.User_Role == selectRole);
foreach (var user in id)
{
var userinfo = from b in db.tblUsers
where b.User_Id == user.User_Id
select new { b.First_Name, b.Last_Name, b.Status, b.Authenticated };
dgvResults.DataSource = userinfo.ToList();
dgvResults.Show();
}
You are assigning the grid in the loop. That is not going to work. Maybe something like this will work:
var userinfo =(from ur in db.tblUsers_Role
join u in db.tblUsers
on ur.User_Id equals u.User_Id
where ur.User_Role == selectRole
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Or a alteretive would be like this:
var roles=db.tblUsers_Role
.Where(a => a.User_Role == selectRole)
.Select (a =>a.User_Id).ToList();
var userinfo=
(
from u in db.tblUsers
where roles.Contains(u.User_Id)
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}
).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Not as nice as the first one. But maybe you understand the concept.

Create ViewModel using multiple models

Build ViewModel using two models
Model 1: Person (Id,Name,Address,Phone,CategoryId)
Model 2: Category(CategoryId,CategoryText)
ViewModel: PersonViewModel (Name,Phone, CategoryText)
Question: how would I generate my ViewModel in my controller and forward it to the view:
var model = (from x in db.Person
select new PersonViewModel {
Name = x.Name,
Phone = x.Phone,
CategoryText = ??? }).ToList();
How do I generate CategoryText?
Thanks
You need to join on categories.
you may be able to include as the following, if not you just need a join. Try the following (I forget if you can include() in this syntax - somethingin my mind tells me you can't and if that's the case I'll delete this shortly as I see someone just posted the join syntax)
var model = (from x in db.Person.Include(o=>o.Category) //assumes EF 4.1 if not try .Include("Category")
select new PersonViewModel {
Name = x.Name,
Phone = x.Phone,
CategoryText = x.Category.CategoryText }).ToList();
var model = (from x in db.Person
join y from db.Category on x.CategoryId equals y.CategoryID
select new PersonViewModel {
Name = x.Name,
Phone = x.Phone,
CategoryText = y.CategoryText }).ToList();

grouping a linq statement, doesnt seem to group

I am having a problem trying to group a small linq query.
The query excutes ok however no grouping happens. I assume its due to having 3 different fields I am trying to group.
var data = (from d in All()
group d by new { d.CustomerNumber, d.TransactionAmount, d.CustomerName }
into g
orderby g.Key.CustomerName
select new TransactionViewModel
{
CustomerNumber = g.Key.CustomerNumber,
TransactionAmount = g.Sum(s=>s.TransactionAmount),
CustomerName = g.Key.CustomerName
});
Ideally I would like to be able to return the grouped data with access to the 3 fields.
What do I need to modify?
Are you sure you have to do group d by new { d.CustomerNumber, d.TransactionAmount, d.CustomerName }
I just removed TransactionAmount from group by as it is diffrent for each row.
TRy this.
(from d in All() group d by new { d.CustomerNumber, d.CustomerName } into g orderby g.Key.CustomerName select new Test { CustomerNumber = g.Key.CustomerNumber, TransactionAmount = g.Sum(s => s.TransactionAmount), CustomerName = g.Key.CustomerName });

MVC Razor Var data

Hi i am new to MVC3 Razor .
I was trying to display the values from the database table.
in controller i wrote the code as
var test1 = from ed in db.EmpDetails
join dp in db.Departments on ed.EmpDept equals dp.DeptId
select new
{
EmpId = ed.EmpId,
EmpName = ed.EmpName,
EmpDesignation = ed.EmpDesignation,
EmpSalary = ed.EmpSalary,
EmpUserName =ed.EmpUserName,
EmpDept =ed.EmpDept,
deptName = dp.deptName
};
ViewBag.test = test1;
and in the view
#foreach (var tm in ViewBag.test)
{
string abc =#tm.EmpName;
// and the logic
}
Here i am getting all the value in the "tm" variable. But when i try to get the particular value of EmpName in a string it is showing the error as "'object' does not contain a definition for 'EmpName'".
Please help me to solve this error.
Thanks
san
Unfortunately anonymous objects doesn't work with Views. Either you need to return a non-anonymous to view Or return a dynamic object to view.
Refer : http://rhizohm.net/irhetoric/post/2011/05/25/Taking-The-M-out-of-MVC-JSON-The-dynamic-Keyword-LINQ-.aspx
You cannot use anonymous objects in views. Try like this:
var test1 =
from ed in db.EmpDetails
join dp in db.Departments on ed.EmpDept equals dp.DeptId
select ed;
ViewBag.test = test1;
and then:
#foreach (var tm in (IEnumerable<Employee>)ViewBag.test)
{
string abc = tm.EmpName;
// and the logic
}
But personally I would recommend you using strongly typed views instead of ViewBag:
var test1 =
from ed in db.EmpDetails
join dp in db.Departments on ed.EmpDept equals dp.DeptId
select ed;
return View(test1);
and inside the view:
#model IEnumerable<Employee>
#foreach (var tm in Model)
{
string abc = tm.EmpName;
// and the logic
}
I am able to get the values in the view if i convert linq result to toList() in controller.
Like
var test = (from p in db.EmpDetails orderby p.EmpName ascending select p).ToList();
ViewBag.test = test;
And in the view
#foreach (var tm in ViewBag.test)
{
int emId = #tm.id;
}
Thanks....

Resources