How do I get the multiple result in a query? - c#

I'm trying to make a query ... I'm using entity framework in the project.
The query below is working
public async Task<dynamic> CriarResumo(Pedido pedido)
{
var query = (from p in context.Pedido
join pi in context.PedidoItem on p.Id equals pi.PedidoId
join t in context.Tamanho on pi.TamanhoId equals t.Id
join s in context.Sabor on pi.SaborId equals s.Id
join pia in context.PedidoItemAdicional on pi.Id equals pia.PedidoItemId
join a in context.Adicional on pia.AdicionalId equals a.Id
where p.Id == pedido.Id
select new
{
tamanho = t.Descricao + " - " + t.ML+"ml",
sabor = s.Descricao,
adicionais = a.Descricao,
tempoPreparo = p.TempoTotal,
valorTotal = p.ValorTotal
});
var o = query.FirstOrDefault();
return o;
}
"Adicional" is an associative table (PedidoItemId and AdicionalId) so it is possible that the search returns more than one result.
Ex: PedidoItem Id = 67
The Item has the Adicional->id 1 and the Adicional->id 2.
The way I'm doing I can only get the Adicional in id 1. How can I solve?

You are using .FirstOrDefault() which returns first element of a sequence or a default value if no item is found. If you want to return a collection of items you should use a method that returns it: e.g. .ToList() or .ToArray()

Related

Have a Query want it in LINQ(Inner Join)

I'm having problem translating a query to LINQ in C# this is my query
select PDF.Name,PDF.Name
from PDF inner join PC
on PDF.Id=PC.Ref_PDF
having pc.Ref_Customer=_id
you should know that _id is something that i send to my method so I can find something with it
so far I did this which I don't think would work(cuase lot's of errors poped up)
Invalid expression term 'select'
and
Expected contextual keyword 'equals'
both at end of here join p in Context.PDFs on c.Ref_PDF
internal List<EF_Model.PDF> Customers_File(int _id)
{
using (var Context = new EF_Model.CoolerEntities())
{
var q = from c in Context.PCs
where c.Ref_Customer == _id
join p in Context.PDFs on c.Ref_PDF
select new { c.PDF.Id, c.PDF.Name, c.PDF.File };
return q;
}
}
How can we make it into a linq statement?
Fix the syntax for the query
List<EF_Model.PDF> Customers_File(int _id) {
using (var Context = new EF_Model.CoolerEntities()) {
var q = from c in Context.PCs
join p in Context.PDFs on c.Ref_PDF equals p.Id
where c.Ref_Customer == _id
select new EF_Model.PDF { Id = c.PDF.Id, Name = c.PDF.Name, File = c.PDF.File };
return q.ToList();
}
}
and the method expects to return a list so use the ToList() on the query when returning from the method.
UPDATE:
If the intention was just to return the PDF model then no need to create the anonymous object just return c.PDF
List<EF_Model.PDF> Customers_File(int _id) {
using (var Context = new EF_Model.CoolerEntities()) {
var q = from c in Context.PCs
join p in Context.PDFs on c.Ref_PDF equals p.Id
where c.Ref_Customer == _id
select c.PDF;
return q.ToList();
}
}
This should do the job for you
from pc in context.PCs where pc.Ref_Customer == _id
join p in context.PDFs on pc.Ref_PDF equals p.Ref_PDF
select new {pc.PDF.Id, pc.PDF.Name, pc.PDF.File }
Probably when you said errors, I assume you saw synactical errors
If you set up a navigation property, the query is:
var q =
from pc in Context.PCs
where pc.Ref_Customer == _id
from pdf in pc.PDFs
select pdf;
If you don't:
var q =
from pc in Context.PCs
where pc.Ref_Customer == _id
join pdf in Context.PDFs on pc.Ref_PDF equals pdf.Id
select pdf;
The main thing to know about the join syntax, it has the form
" join (a) in (b) on (c) equals (d) "
(a): the new range variable for a member of (b)
(b): the source of items you are joining to - the right side of the join.
(c): an expression in which the item from the left side of the join is in scope.
(d): an expression in which the item from the right side of the join is in scope - (a).

Linq with EF method cannot be translated into a store expression(in repository pattern)

i am trying to access data from multiple model in repository pattern using Ling subquery. but when i try to access data in inner query using .GetQueryable() i receive following error.
ERRORLINQ to Entities does not recognize the method 'System.Collections.Generic.List1[<>f__AnonymousType1702[System.Int32,System.Int32]] ToList[<>f__AnonymousType1702](System.Collections.Generic.IEnumerable1[<>f__AnonymousType170`2[System.Int32,System.Int32]])' method, and this method cannot be translated into a store expression.
var query = (from i in
(from student in _tblStudents.GetQueryable()
join Sections in _tblStudentsSections.GetQueryable() on student.StudentID equals Sections.StudentID
join Class in _tblClasses.GetQueryable() on Sections.ClassID equals Class.ClassID
join Program in _tblPrograms.GetQueryable() on Class.ProgramID equals Program.ProgramID
//where student.IsForeign == false
select new
{
ProgramID = Program.ProgramID,
program = Program.ProgramName,
ClassIDs = Sections.ClassID,
TotalSeats = Program.NoOfAdmissions,
IsForeign = student.IsForeign
})
group i by new { i.ProgramID, i.IsForeign, i.TotalSeats, i.program } into grp
select new AdmissionSummaryReportModel
{
program = grp.Key.program,
TotalSeats = grp.Key.TotalSeats,
//SeatsFilled = grp.Select(m => m.ClassIDs).Count(),
AvailableForeignSeats = 22,
SeatsFilled = (int)(from student in _tblStudents.GetQueryable()
join StudentSections in _tblStudentsSections.GetQueryable() on student.StudentID equals StudentSections.StudentID
join Class in _tblClasses.GetQueryable() on StudentSections.ClassID equals Class.ClassID
join Program in _tblPrograms.GetQueryable() on Class.ProgramID equals Program.ProgramID
where student.IsForeign == false && Program.ProgramID == grp.Key.ProgramID
select new
{
StudentSections.ClassID
}).ToList().Count(),
ForeignSeatsFilled = (int)(from student in _tblStudents.GetQueryable()
join StudentSections in _tblStudentsSections.GetQueryable() on student.StudentID equals StudentSections.StudentID
join Class in _tblClasses.GetQueryable() on StudentSections.ClassID equals Class.ClassID
join Program in _tblPrograms.GetQueryable() on Class.ProgramID equals Program.ProgramID
where student.IsForeign && Program.ProgramID == grp.Key.ProgramID
select new
{
StudentSections.ClassID
}).ToList().Count()
}).ToList();
how to overcome this error with .GetQueryable() or provide me any alternative mean
The problem is using the ToList function in your LINQ query, that is not what you want to do, since that cannot be translated to a proper SQL query. You want to use ToList only outside the actual LINQ query. To get the count inside, use the LINQ Count function instead, for instance :
select new
{
StudentSections.ClassID
}).Count()
Queryable gets translated into sql query at runtime, in the subquery you are parsing with int which is known to c# compiler not to query translation.
Either user IEnumerable or remove int as count will return the int.

"cannot implicitly convert .." when using LINQ Where

I'm trying to write a query in a c# program that gets all items out of a database where a particular id in that item is contained in a list I have. I also need to join on a few tables..
What I have is:
var data = from a in db.Apples.Where(a => myApples.contains(a.type))
from b in db.Banans where b.Id = a.bananaPair.Id
from c in db.Coconuts where c.Id = c.coconutPair.Id
select new {
apple = a,
bananaName = b.name,
coconutName = c.name,
});
I get an error on "where b.Id = a.bananaPair.Id" that "cannot implicitly convert int to bool". I think I am mixing types.. the first where is a comparison, and the others is a join condition. How can I do both in the query? I need pieces of information from all 3 tables in my select object.
Thanks
Change it to
var data = from a in db.Apples.Where(a => myApples.contains(a.type))
from b in db.Banans where b.Id == a.bananaPair.Id
from c in db.Coconuts where c.Id == c.coconutPair.Id
select new {
apple = a,
bananaName = b.name,
coconutName = c.name,
});
You had b.Id = a.bananaPair.Id. That assigns a.bananaPair.Id to b.Id. The reason your error was calling this assignment an int is because assignments return the value assigned. You want b.Id == a.bananaPair.Id, which tests whether they're equal.
As commenter #misterManager suggests, you could also use join here. Let me know if this doesn't work, though, it's been so long since I've used query syntax.
var data = from a in db.Apples.Where(a => myApples.contains(a.type))
join b in db.Bananas on a.bananaPair.Id equals b.Id
join c in db.Coconuts on c.coconutPair.Id equals c.Id
select new {
apple = a,
bananaName = b.name,
coconutName = c.name,
});
By the way, I couldn't help but notice your c line: from c in db.Coconuts where c.Id == c.coconutPair.Id, should that be a.coconutPair.Id?

LINQ using dictionary in where clause

er have the following query in linq...
Whenever I try to run it I get a No comparison operator for type System.Int[] exception.
It's got something to do with the dictionary I am sure, but I don't understand why this isn't valid and was wondering if someone could explain?
// As requested... not sure it will help though.
var per = (
from p in OtherContext.tblPeriod
where activeContractList.Select(c => c.DomainSetExtensionCode).Contains(p.DomainSetExtensionCode)
select p).ToArray();
var com = (
from c in MyContext.tblService
join sce in MyContext.tblServiceExtension
on c.ServiceExtensionCode equals sce.ServiceExtensionCode
join sc in MyContext.tblServiceContract
on sce.ServiceContractCode equals sc.ContractCode
group sc by c.Period into comG
select new
{
PeriodNumber = comG.Key,
Group = comG,
}).ToArray();
var code =
(from c in com
join p in per on c.PeriodNumber equals p.PeriodNumber
select new
{
p.Code,
c.Group
}).ToArray();
var payDictionary = new Dictionary<int, int[]>();
// This is another linq query that returns an anonymous type with
// two properties, and int and an array.
code.ForEach(c => payDictionary.Add(c.Code, c.Group.Select(g => g.Code).ToArray()));
// MyContext is a LINQ to SQL DataContext
var stuff = (
from
p in MyContext.tblPaySomething
join cae in MyContext.tblSomethingElse
on p.PaymentCode equals cae.PaymentCode
join ca in MyContext.tblAnotherThing
on cae.SomeCode equals ca.SomeCode
where
// ca.ContractCode.Value in an int?, that should always have a value.
payDictionary[p.Code].Contains(ca.ContractCode.Value)
select new
{
p.Code,
p.ExtensionCode,
p.IsFlagged,
p.Narrative,
p.PayCode,
ca.BookCode,
cae.Status
}).ToList();
You won't be able to do this with a dictionary. The alternative is to join the three linq queries into one. You can do this with minimal impact to your code by not materializing the queries with ToArray. This will leave com and code as IQueryable<T> and allow for you compose other queries with them.
You will also need to use a group rather than constructing a dictionary. Something like this should work:
var per = (
from p in OtherContext.tblPeriod
where activeContractList.Select(c => c.DomainSetExtensionCode).Contains(p.DomainSetExtensionCode)
select p.PeriodNumber).ToArray(); // Leave this ToArray because it's materialized from OtherContext
var com =
from c in MyContext.tblService
join sce in MyContext.tblServiceExtension on c.ServiceExtensionCode equals sce.ServiceExtensionCode
join sc in MyContext.tblServiceContract on sce.ServiceContractCode equals sc.ContractCode
group sc by c.Period into comG
select new
{
PeriodNumber = comG.Key,
Group = comG,
}; // no ToArray
var code =
from c in com
where per.Contains(c.PeriodNumber) // have to change this line because per comes from OtherContext
select new
{
Code = c.PeriodNumber,
c.Group
}; // no ToArray
var results =
(from p in MyContext.tblPaySomething
join cae in MyContext.tblSomethingElse on p.PaymentCode equals cae.PaymentCode
join ca in MyContext.tblAnothThing on cae.SomeCode equals ca.SomeCode
join cg in MyContext.Codes.GroupBy(c => c.Code, c => c.Code) on cg.Key equals p.Code
where cg.Contains(ca.ContractCode.Value)
select new
{
p.ContractPeriodCode,
p.DomainSetExtensionCode,
p.IsFlagged,
p.Narrative,
p.PaymentCode,
ca.BookingCode,
cae.Status
})
.ToList();
Side Note: I also suggest using navigation properties where possible instead of joins. It makes it much easier to read and understand how objects are related and create complex queries.

Entity Framework query error?

I'm getting this error:
The entity or complex type 'Model.Members' cannot be constructed in a LINQ to Entities query.
with my code:
public List<Members> getTeamMembers(String tem_reference)
{
var query = from c in cecbContext.Projects
join b in cecbContext.TeamMembers on c.proj_team equals b.team_reference
join d in cecbContext.Members on b.mem_reference equals d.mem_reference
where c.proj_reference == tem_reference
select new Members
{
mem_reference = d.mem_reference
};
return query.ToList<Members>();
}
I believe you're running into problems because you're trying to project a mapped entity, and this answer would tell you more: https://stackoverflow.com/a/5325861/2208058
This is what I think might work for you:
var query = from c in cecbContext.Projects
join b in cecbContext.TeamMembers on c.proj_team equals b.team_reference
join d in cecbContext.Members on b.mem_reference equals d.mem_reference
where c.proj_reference == tem_reference
select d.mem_reference;
return query.Select(ref => new Members { mem_reference = d.mem_reference }).ToList();

Categories