How can I add Sum from another Table in my Model? - linq

So I have my View setup like this in the controller:
public ActionResult View(Guid projectID)
{
OnboardModel model = context.onboard_projectInfos.Where(x => x.projectID == projectID).Select(x =>
new OnboardModel()
{
propertymanagername = x.propertymanagername,
propertymanagercontactemail = x.propertymanagercontactemail,
date_modified = (DateTime)x.date_modified,
projectmanagercontactnumber = x.projectmanagercontactnumber,
Developer = x.onboard_projectCreate.Developer,
status1 = x.onboard_projectCreate.status1,
ProjectName = x.onboard_projectCreate.ProjectName
}).SingleOrDefault();
var pix = projectID.ToString();
context.onboard_BuildingInfos.Where(x => x.buildprojectID == pix).GroupBy(x => x.buildprojectID).Select(g => {
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
});
return View(model);
}
Problem is grabbing the sum of numberofres and numberofcommer from BuildingInfos.
Using .Select gives me the error:
Error CS0411 The type arguments for method 'Queryable.Select(IQueryable, Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How to I write this LINQ statement correctly?
Thanks.

You cannot modify an object within a select (you can only create a new object). Further, you can't add new properties to an existing object.
We'll assume that OnboardModel defines the totalres and totalcom properties.
var query = context.onboard_BuildingInfos
.Where(x => x.buildprojectID == pix)
.GroupBy(x => x.buildprojectID);
foreach(var g in query)
{
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
}

Related

Replacing empty values with a default value in a Linq to Entities query

In the Linq to Entities query below I need to place a default value in the x.Number in the returned value if the query returns 0 OfficeTelephone objects. I have tried
x.Number??"555-1212" but that throws an error.
from c in Contacts
.Where(a => a.LastName.Contains("ANDUS")).Take(10)
select new
{
Id = c.Id,
OfficeTelephone = c.Telephones.Where(a=>a.TelephoneType.Name.Contains("Office")).Select(x => new { x.AreaCode, x.Number, x.TelephoneType, x.Primary })
}
I've tried something like:
from c in Contacts
.Where(a => a.LastName.Contains("ANDUS")).Take(10)
select new
{
Id = c.Id,
OfficeTelephone = c.Telephones
.Where(a=>a.TelephoneType.Name.Contains("Office"))
.Select(x => new { x.AreaCode, x.Number, x.TelephoneType, x.Primary })
.DefaultIfEmpty()}
But I'm not sure how to push a default object into the DefaultIFEmpty()
Use DefaultIfEmpty and pass a default instance with those value which you would want by default i.e. if no rows are returned.
try it like this:
Contacts.Where(a=>a.LastName.Contains("ANDUS"))
.Take(10)
.Select(x => new
{
Id = x.Id,
OfficeTelephone = x.Telephones
.Where(a=> a.Telephone.Name.Contains("Office"))
.Select(b=> new Telephone
{
b.AreaCode,
b.Number,
b.TelephoneType,
b.Primary
})
.DefaultIfEmpty(new Telephone())
});
where I've assumed that typeof(x.Telephones) == typeof(List<Telephone>)

EF and LINK query not giving all table values in "select"

How do I use a column in the "where" that I haven't inluded in the "select"? The "where" method isn't showing me all the columns in my SQL Server table, only the 3 in the select statement. I need to do the select based on a different column in the table:
using (var context = new URIntakeEntities())
{
return context.Claims.Select(
u => new Models.Claim
{
ClaimNumber = u.ClaimNumber,
DateOfInjury = u.DateOfInjury,
Denied = u.Denied
}).Where(u => u.?????).ToList();
}
You should move your where statement before the select statement.
using (var context = new URIntakeEntities())
{
return context.Claims.Where(u=> u.?????).Select(
u => new Models.Claim
{
ClaimNumber = u.ClaimNumber,
DateOfInjury = u.DateOfInjury,
Denied = u.Denied
}).ToList();
}
How do I use a column in the "where" that I haven't included in the
"select"?
You can't. Where is applied on a current type of sequence. So, you should apply filter before projecting result:
using (var context = new URIntakeEntities())
{
return context.Claims
.Where(u => u.?????)
.Select(u => new Models.Claim
{
ClaimNumber = u.ClaimNumber,
DateOfInjury = u.DateOfInjury,
Denied = u.Denied
}).ToList();
}

Linq select subquery

As the title states, I'm trying to perform a select subquery in Linq-To-SQL. Here's my situation:
I have a database view which returns the following fields:
SourceId
LicenseId
LicenseName
CharacteristicId
CharacteristicName
Now I want to be able to store this in a model of mine which has the following properties
Id
Name
Characteristics (this is List which has Id, Name and Icon => Icon is byte[])
Here's the query I wrote which doesn't work:
var licensesWithCharacteristics =
_vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.SourceID == sourceId)
.Select(a => new LicenseWithCharacteristicsModel()
{
LicenseId = a.LicenseId,
LicenseName = a.LicenseName
,CharacteristicList = _vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.LicenseId == a.LicenseId)
.Select(c => new CharacteristicModel { Id = c.CharacteristicID, Name = c.CharacteristicName, Icon = c.Icon })
.Distinct().ToList()
})
.Distinct().ToList();
How would you solve this? I'm trying to do this in one query to keep my performance up, but I'm kind of stuck.
Your sample query and models are not that coherent (where does Icon come from, Characteristics or CharacteristicList), but anyway.
I do this in two parts, you can of course regroup this in one query.
I enumerate the result after the grouping, you may try to do without enumerating (all in linq to sql, but not sure it will work).
var groupedResult =
_vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.SourceID == sourceId)
.GroupBy(m => new {m.LicenseId, m.LicenseName})
.ToList();
var results = groupedResult.Select(group => new LicenseWithCharacteristicsModel {
LicenseId = group.Key.LicenseId,
LicenseName = group.Key.LicenseName,
Characteristics = group.Select(m=> new CharacteristicModel {
Id = m.CharacteristicId,
Name = m.CharacteristicName
}).ToList()
});
in "single query"
_vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.SourceID == sourceId)
.GroupBy(m => new {m.LicenseId, m.LicenseName})
.Select(group =>
new LicenseWithCharacteristicsModel
{
LicenseId = group.Key.LicenseId,
LicenseName = group.Key.LicenseName,
Characteristics = group.Select(m =>
new CharacteristicModel
{
Id = m.CharacteristicId,
Name = m.CharacteristicName
}).ToList()
});

Selecting related pairs LINQ

I'm using LINQ to manipulate a datatable. I have 3 columns - I would like group by one and then select the remaining 2 columns together. At the moment I have something like this
var query = reportDataTable.AsEnumerable()
.GroupBy(c => c["Code"])
.Select(g =>
new {
Code = g.Key,
Rank = g.Select(f => new
{ f["rank"],
f["Name"]}).ToArray()
});
but I get issues due to anonymous types. I know this syntax would work if I could reference the the column headers directly (in say a list or w/e). How can I get around this with DataTables? Cheers.
Edit:
Well I'd like to be able to reference the fields later when I come to populate the data into a different datatable:
foreach (var q in query)
{
DataRow df = dp.NewRow();
df["Code"] = q.Code;
foreach (var rank in q.Rank)
{
df[rank.name] = rank.rank;
}
dp.Rows.Add(df);
}
define your Rank fields, Also if you have a class for it, call related class constructor,
you can see this in bellow code, before ToArray.
var query = reportDataTable.AsEnumerable()
.GroupBy(c => c["Code"])
.Select(g =>
new { Code = g.Key, Rank =
g.Select(f => new { rank = f["rank"], name = f["Name"]})
.ToArray() });

Weird behaviour with Linq

I have a Windows forms application (.NET 4.0) running with a Sql Server CE 3.5 database, which I access via an EF connection.
Here is my initial query, which returns two results:
var list = db.UserPresentation
.Select(up => new
{
UserPresentationID = up.UserPresentationID,
PresentationName = up.PresentationName,
DateRequested = up.DateRequested,
Edit = string.Empty,
Delete = string.Empty,
Download = string.Empty
})
.OrderByDescending(up => up.DateRequested)
.ToList();
Now I introduce an external variable and a where clause, and it returns zero results. If I run this same code in LinqPad, it returns 2 results.
int userID = 2;
// load list of user presentations
var list = db.UserPresentation
.Where(up => up.UserID == userID)
.Select(up => new
{
UserPresentationID = up.UserPresentationID,
PresentationName = up.PresentationName,
DateRequested = up.DateRequested,
Edit = string.Empty,
Delete = string.Empty,
Download = string.Empty
})
.OrderByDescending(up => up.DateRequested)
.ToList();
Now I hardcode the userid inside the query, and it returns two results again:
var list = db.UserPresentation
.Where(up => up.UserID == 2)
.Select(up => new
{
UserPresentationID = up.UserPresentationID,
PresentationName = up.PresentationName,
DateRequested = up.DateRequested,
Edit = string.Empty,
Delete = string.Empty,
Download = string.Empty
})
.OrderByDescending(up => up.DateRequested)
.ToList();
I'm really stumped. Any idea what's going on here?
Is UserID nullable?
If so be sure to do .Where(up => up.UserID.HasValue && up.UserID.Value == userID)
I had something similar with a nullable datetime once
Have you tried assigning the same hard coded value inside your variable? My guess is that the value in your variable is not found among your data, that is if you are sure that the variable name is correct.

Resources