convert rows to column in entity framwork - c#

how can i convert rows to column in entity framework!?
i have a result like this:
and i want this result:
my entity code i this :
(from loanPerson in context.LoanPersons.AsParallel()
join warranter in context.Warranters.AsParallel() on loanPerson.Id equals warranter.LoanPersonId
where loanPerson.Id == 84829
select new
{
loanPersonId = loanPerson.Id,
waranterId = warranter.WarranterPersonID,
}).ToList();
and number of the row always less than 3 and i want to have 3 column.
please let me know your answer.
tanks.

This query will return the only one row, where waranterIds will contain, at this particular case, three WarranterPersonID values, also this field is of List<int> type, because it's quantity not known at compile time:
var answer = (from loanPerson in context.LoanPersons.Where(x => x.Id == 84829)
join warranter in context.Warranters
on loanPerson.Id equals warranter.LoanPersonId
group warranter by loanPerson.Id into sub
select new
{
loanPersonId = sub.Key,
waranterIds = sub.Select(x => x.LoanPersonId).ToList()
//if you sure, that quantity equals 3,
//you can write this code instead of waranterIds:
//zamen1 = sub.Select(x => x.LoanPersonId).First(),
//zamen2 = sub.Select(x => x.LoanPersonId).Skip(1).First(),
//zamen3 = sub.Select(x => x.LoanPersonId).Skip(2).First()
}).ToList();

Related

LINQ: select specific value in a datatable column

In table I have 4 Columns GroupName, Display, Value and ID
How can I just show a specific data in display. I only want to show some of the groupNames Data
for example I only want to show Groupname = company and display = Forbes
Here's my linq
sample = (from c in smsDashboardDBContext.CodeDefinitions
orderby c.Display ascending
select new CodeDefinitionDTO
{
GroupName = c.GroupName,
Display = c.Display,
Value = c.Value,
Id = c.Id
}).ToList();
You can add a where statement in the query.
where c.GroupName == "company" && c.Display == "Forbes"
I only want to show some of the groupNames Data for example I only want to show Groupname = company and display = Forbes
Before the ToList, use a Where to keep only those items that you want to show:
var company = ...
var forbes = ...
var result = smsDashboardDBContext.CodeDefinitions
.OrderBy(codeDefinition => codeDefintion.Display)
.Select(codeDefinition => new CodeDefinitionDTO
{
Id = codeDefinition.Id,
GroupName = codeDefinition.GroupName,
Display = codeDefinition.Display,
Value = codeDefinition.Value,
})
.Where(codeDefinition => codeDefition.GroupName == company
&& codeDefintion.Display == forbes);
In words:
Order all codeDefinitions that are in the table of CodeDefintions by ascending value of property codeDefintion.Display.
From every codeDefinition in this ordered sequence make one new CodeDefinitionDTO with the following properties filled: Id, GroupName, Display, Value
Frome every codeDefintion in this sequence of CodeDefinitionDTOs, keep only those codeDefinitions that have a value for property GroupName that equals company and a value for property Display that equals forbes.
There is room for improvement!
Suppose your table has one million elements, and after the Where, only five elements are left. Then you will have sorted almost one million elements for nothing. Consider to first do the Where, then the Order and finally a Select.
In LINQ, try to do aWhere as soon as possible: all following statements will have to work on less items
In LINQ, try to do a Select as late as possible, preferrably just before the ToList / FirstOrDefault / ... This way the Select has to be done for as few elements as possible
So first the Where, then the OrderBy, then the Select, and finally the ToList / FirstOrDefault, etc:
var result = smsDashboardDBContext.CodeDefinitions
.Where(codeDefinition => ...);
.OrderBy(codeDefinition => codeDefintion.Display)
.Select(codeDefinition => new CodeDefinitionDTO
{
...
});

Compare 2 lists and reduce quantities of resulting list

I have 2 lists
grpoList
I have a second named assembly
I have the following code
grpoList = grpoList.Where(c => assembly.Exists(cr => cr.ItemCode == c.ItemCode)).ToList();
This returns
How do I amend the code such that the line of DocEntry 393 on the results has a quantity of 2 instead of 4?
You probably want to perform a Join between the list and select the required fields out of it like
var data = grpoList.Join(assembly,
x => x.ItemCode,
y => y.ItemNo,
(x, y) => new
{
DocEntry = x.DocEntry,
LineNum = x.LineNum,
CarCode = x.CarCode,
ItemCode = x.ItemCode,
OpenQty = y.OpenQty,
DocDate = x.DocDate
}).ToList();
we can use linq joins to create the custom outputs:
var query = from c in grpoList
join cr in assembly
on c.ItemCode equals cr.ItemCode
select new
{
c.DocEntry,
c.LineNum,
c.CarCode,
c.ItemCode,
OpenQty = c.OpenQty - cr.OpenQty,
c.DocDate
};
Keeping name c and cr same as your question so that you can understand it easily.

Query Row count from Grouped EF query

I have this query to group the levels of a particular row in EF
var awards = from a in context.Awards
where a.TWID == employee.TWID
group a by a.AwardLevel;
This gives me the awards for each level (1-4) what I'm trying to figure out is how to extract the count from the awards for a specific level.
ie: level1.count,level2.count etc.
I know this should be some simple lambda expression or something but I just can't get it.
UPDATE What I'm looking for is a way NOT to write 4 different queries. For example:
var level1 = awards.Level[0]
var level2 = awards.Level[1]
Try:
var awards = from a in context.Awards
where a.TWID == employee.TWID
group a by a.AwardLevel into award
select new
{
AwardLevel = award.Key,
Count = award.Count()
};
Update based on updated question:
var awards = (from a in context.Awards
where a.TWID == employee.TWID
group a by a.AwardLevel into award
select new
{
AwardLevel = award.Key,
Count = award.Count()
}).ToDictionary( t => t.AwardLevel, t => t.Count );

linq-to-sql getting sequence contains more than one element

I have a query that looks like this: it takes a list of IDs (ThelistOfIDs) as parameter and I'm grouping for a count.
var TheCounter = (from l in MyDC.SomeTable
where ThelistOfIDs.Contains(l.ID)
group l by l.Status into groups
select new Counter()
{
CountOnes = (from g in groups
where g.Status == 1
select g).Count(),
CountTwos = (from g in groups
where g.Status == 2
select g).Count(),
}).Single();
And basically, I don't understand why I'm getting the error. I don't want to brring back the entore collection from the DB and do the count in linq-to-object; I want to do the count in the DB and bring back the result.
I have not put your query into my IDE or compiled with C#, but I guess the problem is that
groups in your query is IGrouping<Tkey, Telm> and not IQueryable<Tkey>
(where Tkey is type of l.Status and Telm is type of l).
I think you got confused with the use of grouping operator.
What you want to get is I guess:
var queryByStatus = from l in MyDC.SomeTable
where ThelistOfIDs.Contains(l.ID)
group l by l.Status;
var counter = new Counter()
{
CountOnes = queryByStatus.Where(l => l.Key == 1).Count(),
CountTwos = queryByStatus.Where(l => l.Key == 2).Count(),
};
EDIT:
Alternative query, to obtain the same, moving all operation on DB into the original query so that DB is queried only once.
var queryCountByStatus = from l in MyDC.SomeTable
where ThelistOfIDs.Contains(l.ID)
group l by l.Status into r
select new { status = r.Key, count = r.Count() };
var countByStatus = queryCountByStatus.ToList();
var counter = new Counter()
{
CountOnes = countByStatus.FirstOrDefault(l => l.status == 1).count,
CountTwos = countByStatus.FirstOrDefault(l => l.status == 2).count,
};
Note:
The query in my edit section queries the DB once only and mapping Status -> Count is returned.
Note that in my original query there were two calls to DB needed only - both of which returned single number - one for CountOnes, one for CountTwos.
In the edit query, one query is done which return table { { 1, CountOnes}, {2, CountTwos } }. The other lines are just to convert the result - which is set of items - into single object having certain objects as properties and is done physically on these two values.
You are grouping by Status, and then projecting from that group - but you will still have one row per unique Status (===group).
So: I propose that you don't have exactly one unique Status.
This might be what you're looking for to get...
(it's for users table I had but should be the same)
var statuscounts = (from u in db.Users
where u.UserStatus > 0
group u by u.UserStatus into groups
select new { Status = groups.Key, Count = groups.Count() });
// do this to iterate and pump into a Counter at will
foreach (var g in statuscounts)
Console.WriteLine("{0}, {1}", g.Status, g.Count);
...or even something like this...
var counter = statuscounts.AsEnumerable()
.Aggregate(new Counter(), (c, a) => {
switch (a.Status)
{
case 1: c.CountOfOnes = a.Count; return c;
case 2: c.CountOfTwos = a.Count; return c;
case 3: c.CountOfThrees = a.Count; return c;
default: c.CountOfOthers = a.Count; return c;
}});
...point is that if you're grouping already you should use the grouping result, it's of type IGrouping<out TKey, out TElement> where the key is your status and it's IEnumerable<> or your records.
hope this helps

Linq To Entities

I have a small problem in my where clause in the linq expression below. If I put the number 3 instead of department.Id I get the desired result but when I use department.Id I get nothing in the resultset.
I also want to get a count for the number of filters for that filter name using the query again using distinct.
var dept = Page.RouteData.Values["department"];
var department = (from d in db.Departments
where d.Name.Replace(" ", "-") == dept
select new {d.Id, d.Name}).FirstOrDefault();
var query = from p in db.Products
join f in db.ProductFilters on p.Id equals f.ProductId into filters
from x in filters.Where(x => x.Product.DepartmentId == department.Id
/* if == 3 it works */)
select new { x.Name, x.Id };
Promoted to answer from comments:
Have you checked that the department instance is as you think it should be after the first linq statement - ie has an Id == 3?
Your first query is not finding any valid department and is therefore returning default which most probably means that departmend.Id == 0.

Categories