Linq Convert anonymous to entity object by select - c#

var reassignForms = _formQueryRepository.WithRelatedEntities()
.Where(x => x.Id == formId && x.SchoolId == schoolId)
.Select(y => y.FormUsers.Where(m => m.CanEdit).Select(z => new ReassignFormDTO
{
Name = z.UserProfile.FullName,
Id = z.UserProfile.Id,
Email = z.UserProfile.Email,
Role = z.UserProfile.UserRole,
}));
I want to convert it to ReassignFormDTO but somehow it is returning an object which I cannot convert. I want this to be direct object not [0].objects.

You can use .FirstOrDefault() then it will return the first entity from the linq query. According to the debug window you have two ReassignFormDTO objects and seems like you would like to get only one.
Please provide more detail, so we can help more. Not sure if my previous answer will help you.
EDIT: I didn't noticed the second select inside you statement. According to the comments .SelectMany(z => z) should help you out.

Related

QueryOver in NHibernate

I'm lost when it comes to to QueryOver in NHibernate, I'm trying to query over a database and retrive 4 values of importans, the rest are unnecessary and take up processing power.
I'm trying this:
var ext = _session.QueryOver<ExternServiceSettings>()
.Where(x => x.ExternService == ExternServiceEnum.Outlook).List();
which works fine but takes too long and returns everything in the database. then I tried:
var ext = _session.QueryOver<ExternServiceSettings>()
.Where(x => x.ExternService == ExternServiceEnum.Outlook)
.List<ExternServiceSettings>()
.Select(y => y.UserName);
However this only return the username and won't let me fetch more than one value...
All help is appreciated!
We should use .SelectList()
Check the example from doc:
var selection =
session.QueryOver<Cat>()
.SelectList(list => list
.Select(c => c.Name)
.SelectAvg(c => c.Age))
.List<object[]>();
see more here:
16.7. Projections

Getting list of child entity nested several levels with LINQ

I have entities that are nested in this order:
RootDomain
Company
CompaniesHouseRecord
CompanyOfficer
When given a RootDomain I want to create a list of all CompanyOfficers that have an email address but I am not sure how to do this.
Here Is my non-working attempt:
RootDomain rd = db.RootDomains.Find(123);
List<CompanyOfficer> col = rd.Companies.Where(x => x.CompaniesHouseRecords.Any(chr => chr.CompanyOfficers.Any(co => co.Email != null)))
.Select(x => x.CompaniesHouseRecords.Select(chr => chr.CompanyOfficers)).ToList();
I am obviously way off the mark here. Can someone show me or point me to the correct method for dong this?
Like this:
RootDomain rd = db.RootDomains.Find(123);
List<CompanyOfficer> col = rd.Companies
.SelectMany(c => c.CompaniesHouseRecords)
.SelectMany(c => c.CompanyOfficers)
.Where(o => null != o.Email).ToList();
Someone answered before me, but I can show something different, which can be more convenient for someone who is used to DB requests.
Using LINQ, you can do this type of request:
var officersWithEmail = from company in rd.Companies
from companiesHouseRecord in company.CompaniesHouseRecords
from companyOfficer in companiesHouseRecord.CompanyOfficers
where (companyOfficer.Email != null)
select companyOfficer;
Some people will find it more readable.
If you want to obtain a List<> as output, just use .ToList on the query.

Retain default order for Linq Contains

I want to retain the default order that comes from sql, after processing by Linq also.I know this question has been asked before. Here is a link Linq Where Contains ... Keep default order.
But still i couldn't apply it to my linq query correctly. could anyone pls help me with this? Thanks!
Here is the query
var x = db.ItemTemplates.Where(a => a.MainGroupId == mnId)
.Where(a => a.SubGruopId == sbId)
.FirstOrDefault();
var ids = new List<int> { x.Atribute1, x.Atribute2, x.Atribute3, x.Atribute4 };
var y = db.Atributes.Where(a => ids.Contains(a.AtributeId))
.Select(g => new
{
Name = g.AtributeName,
AtType = g.AtributeType,
Options = g.atributeDetails
.Where(w=>w.AtributeDetailId!=null)
.Select(z => new
{
Value=z.AtributeDetailId,
Text=z.AtDetailVal
})
});
Your assumption is wrong. SQL server is the one that is sending the results back in the order you are getting them. However, you can fix that:
var x = db.ItemTemplates.Where(a => a.MainGroupId == mnId)
.Where(a => a.SubGruopId == sbId)
.FirstOrDefault();
var ids = new List<int> { x.Atribute1, x.Atribute2, x.Atribute3, x.Atribute4 };
var y = db.Atributes.Where(a => ids.Contains(a.AtributeId))
.Select(g => new
{
Id = g.AtributeId,
Name = g.AtributeName,
AtType = g.AtributeType,
Options = g.atributeDetails
.Where(w=>w.AtributeDetailId!=null)
.Select(z => new
{
Value=z.AtributeDetailId,
Text=z.AtDetailVal
})
})
.ToList()
.OrderBy(z=>ids.IndexOf(z.Id));
Feel free to do another select after the orderby to create a new anonymous object without the Id if you absolutely need it to not contain the id.
PS. You might want to correct the spelling of Attribute, and you should be consistent in if you are going to prefix your property names, and how you do so. Your table prefixes everything with Atribute(sp?), and then when you go and cast into your anonymous object, you remove the prefix on all the properties except AtributeType, which you prefix with At. Pick one and stick with it, choose AtName, AtType, AtOptions or Name, Type, Options.

OrderByDescending with a date from another table(s)

Hopefully this question is not to confusing. Basically I'm looking for pointers on how to OrderByDecending with a date from relational tables. I have constructed a basic method that looks like it could possibly work but I'm getting errors:
DbSortClause expressions must have a type that is order comparable.
Parameter name: key
I understand what this is saying but I'm not entirely sure how to fix using Linq method syntax.
public BusinessEntities.Application GetLastUpdatedAppliction(int userID)
{
return context.tbl_User_To_Application
.Where(x => x.UserID == userID)
.OrderByDescending
(o => o.tbl_Application.tbl_ApplicationChanges
.Where(oo => oo.ApplicationID == o.ApplicationID)
.Select(s => s.ChangeDate))
.ThenByDescending(t => t.DateAdded)
.Select(y => new BusinessEntities.Application
{
ApplicationID = y.tbl_Application.ApplicationID,
ApplicationName = y.tbl_Application.ApplicationName
}).FirstOrDefault();
}
Basically I have a cross reference table that binds a user to a specific application(Website) Then inside I need to nest into two tables to get the latest changes to the Application with a "ChangesDate". So ideally this would return the last updated application. Then obviously populates my DTO.
I'm still trying to get to grips with Linq method syntax so any help would be greatly appreciated!
Regards,
Tez Wingfield
If you want to order by the last application change date:
(...)
.OrderByDescending(o =>
o.tbl_Application.tbl_ApplicationChanges
.Where(ac => ac.ApplicationID == o.ApplicationID)
.OrderByDescending(ac => ac.ChangeDate)
.First()
.Select(ac => ac.ChangeDate)
)
(...)

Linq select with filtering not working

I'm trying to select one field last record in filtered database (this is different than last inserted record). I tried with following code in controller but instead of field value, i'm getting "true" or "false", depending on if there's results after filtering or not.
List<Pozicije> poz = new List<Pozicije>();
poz = db.Pozicijes.Where(p => p.grupa == grupa)
.OrderBy(p => p.sifra_pozicije).ToList();
string pos = poz.Select(p => p.sifra_pozicije.Contains(s)).LastOrDefault().ToString();
can someone point me how to get value i need instead?
Try this instead. I've combined both parts of your query into one.
var pos =
Convert.ToString(db.Pozicijes.Where(p => p.grupa == grupa
&& p.sifra_pozicije.Contains(s))
.OrderByDescending(p => p.sifra_pozicije)
.Select(p => p.sifra_pozicije)
.FirstOrDefault());
If it doesn't work, you may need to tell us what types s and sifra_pozicije are.
LastOrDefault is not supported with LINQ to Entities/LINQ TO SQL. You need to do OrderByDescending and then get First record. Like:
string pos = db.Pozicijes.Where(p => p.grupa == grupa && p.sifra_pozicije.Contains(s)))
.OrderByDescending(p=> p.sifra_pozicije)
.Select(r=> r.sifra_pozicije)
.First();

Categories