Linq distinct problem - linq

I am new to using LINQ, right now i have a query in sql with multiple inner joins and it works fine. I am trying to change this to a equivalent LINQ code, i could able to implement LINQ except for the Distinct fact i am using in my query...
my query
select DT.[Name], count(distinct([FeatureControlID])) as [Value], DT.[Weight]
from [DocumentTypes] DT inner join
[DocumentTypesSchema] DTS on
DT.[ID] = DTS.[DocumentTypeID] inner join
ProductsFeaturesControlsDocumentValues [PFCDV] on
DTS.[ID] = PFCDV.[SchemaID]
where [PFCDV].[ProductID] = 72
group by DT.[Name], DT.[Weight], [DT].[ID]
order by [DT].[ID]
and my LINQ without the Distinct condition is as below
from dt in db.DocumentTypes
join dts in db.DocumentTypesSchemas on new { ID = dt.ID } equals new { ID = dts.DocumentTypeID }
join pfcdv in db.ProductsFeaturesControlsDocumentValues on new { ID = dts.ID } equals new { ID = pfcdv.SchemaID }
where
pfcdv.ProductID == 72
group new {dt, pfcdv} by new {
dt.Name,
dt.Weight,
dt.ID
} into g
orderby
g.Key.ID
select new {
g.Key.Name,
Value = (Int64?)g.Count(p => p.pfcdv.FeatureControlID != null),
Weight = (System.Decimal?)g.Key.Weight
}
can anyone give me a hand on this? actually the linq code executes without the Distinct feature i used in the code.

Have you tried something like this?
...
select new {
g.Key.Name,
Value = (Int64?)g.Select(p => p.pfcdv.FeatureControlID)
.Where(id => id != null)
.Distinct().Count()
Weight = (System.Decimal?)g.Key.Weight
}

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)
};

Entity Framework query: object not set to an instance of an object

When calling the query.ToList() I get
object reference not set to an instance of an object
For x.Gallons, all the orders have this value set, it's not null. Also, there are 2 DProducts in the database table with proper ID. What could be wrong?
ProductSummaryCollection.Clear();
var query = from p in Repository.repository.ctx.DProduct
join fo in Repository.repository.ctx.DFuelOrder.Include("DProduct")
on p.ID equals fo.DProductID
group fo by fo.DProduct into Prod
select new DProductSummary
{
Product = fo.DProduct,
TotalGallons = (float)Prod.Sum(x => x.Gallons)
};
try
{
IList<DProductSummary> ps = query.ToList();
foreach (DProductSummary dps in ps)
ProductSummaryCollection.Add(dps);
}
catch (Exception exc)
{
}
It seems that you can't do the following 2 things:
Create a entity object, DProduct in my case inside a linq query
You cannot access a reference in a linq query even if you Include it
So you have to use the join table.Propery instead.
A working query:
var query = from fo in Repository.repository.ctx.DFuelOrder.Include("DProduct")
join p in Repository.repository.ctx.DProduct
on fo.DProductID equals p.ID
group fo by new { fo.DProductID, p.Name } into Prod
select new DProductSummary
{
ProductName = Prod.Key.Name,
TotalGallons = (float)Prod.Sum(x => x.Gallons)
};

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.

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 });

Access any data that is not contained in grouped element

from teamBudget in TeamBudgets
where teamBudget.TeamID == 71002
join teamBroker in TeamBrokers on 71002 equals teamBroker.TeamID
join goal in Goals on teamBroker.GlobalBrokerID equals goal.GlobalBrokerID
group goal by goal.GlobalBrokerID into g
select new
{
// TeamID=teamBroker.TeamID,
// MTDGoal=teamBudget.Sum(t => t.Budget),
RevenueMTDCurrent = g.Sum(x => x.RevenueMTDCurrent)
}
Commented part is a problem. How to access any data that is not contained in grouped element?
you need to Group multiple fields then only you can access that data.
like
var result = from i in
(from uh in db.UserHistories
where uh.User.UserID == UserID && uh.CRMEntityID == (int)entity
select new { uh.ActionID, uh.ActionType, uh.ObjectID })
group i by new { i.ActionID, i.ActionType, i.ObjectID } into g
select new { g.ActionID, g.ActionType, g.ObjectID };
Hope this will help

Resources