Is this possible with Dapper? - sql

If you have a Customer object that has a List<Orders> property how can you select the customers you want and then apply the orders for that customer to the List<Orders> property for each one?
The only way I can think is to loop over customers and hit the database N times for the relevant orders against that customer.
var sql = #"
select * from Customers
select * from Orders where CustomerId = #id";
using (var multi = connection.QueryMultiple(sql))
{
var customers = multi.Read<Customer>();
//Get orders for each result in customers and apply
//Customer.Orders property to result
var orders = multi.Read<Order>().ToList();
}

You should use multi-mapping. From Dapper documentation:
var sql =
#"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();
post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);
In your code Users will be Customers, and Orders will be Posts
Edit I realize that this is not exactly what your want. So, in your case you can use QueryMultiple, but then matching the records from both lists with linq, avoiding hitting the Db N times:
var sql = #"select * from Customers
select * from Orders";
using (var multi = connection.QueryMultiple(sql))
{
var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
}
foreach c in customers {
c.Orders = (from rec in orders where rec.CustomerId == c.Id select rec).ToList()
}
Edit refactor for better performance if you have several filter in Customers
var customers = connection.Query<Customer>("select * from Customers
where blah, blah, blah, blah, .. ").ToList();
var orders = connection.Query<Order>("select * from Order where CustomerID in #Ids",
new { Ids = (from rec in customers select rec.Id).ToList()}).ToList();
foreach c in customers {
c.Orders = (from rec in orders where rec.CustomerId == c.Id select rec).ToList()
}

Related

select some ids from sql in linq

hi I'm using the query below to select studentId and Score from table1 now i want select users that i selected their ids from table2, how i can select it with ids?
i can select users with this query from v in dc.tbl_Students select v but i want select some users that i have their id.
var qBestMan = (from T in (((from tbl_ActPoints in dc.tbl_ActPoints
select new
{
StudentId = (int?)tbl_ActPoints.StudentId,
Score = (int?)tbl_ActPoints.Score
}).Concat(
from tbl_EvaPoints in dc.tbl_EvaPoints
select new
{
StudentId = (int?)tbl_EvaPoints.StudentId,
Score = (int?)tbl_EvaPoints.Score
})))
group T by new
{
T.StudentId
} into g
orderby g.Sum(p => p.Score) descending
select new
{
g.Key.StudentId,
HighScoreUser = g.Sum(p => p.Score)
}).ToArray();
Try something like this:
//qBestMan must be a List, or a IEnumarable and not a Array. Remove the .ToArray() at the end, or substitute it by .ToList()
var Result = from users in dc.tbl_Students
join bestMen in qBestMan on bestMen.StudentId equals users.userid
select new
{
//fields that you want
example = users.example,
other = bestMen.other
};

SQL to LINQ query equivalent

Hello I need to crate linq query from this SQL:
SQL:
select
p.id,
p.Name,
sum(h.Hour)
from
dbo.Hour h
INNER JOIN dbo.ProjectView p ON h.ProjectId = p.Id
WHERE
h.PeopleId = 7999
group by
p.Name, p.Id
LINQ: I tried this but it is not the same:
var query = from hours in _hourRepository.GetAll()
join proj in _projectRepository.GetAll() on hours.ProjectId equals proj.Id
where hours.PeopleId == personId
group hours by new { proj.Id, proj.Name, proj.Flag, hours.Hours } into g
select new PopleProjectsSumDto
{
Id = g.Key.Id,
Name = g.Key.Name,
Flag = g.Key.Flag,
Hours = g.Sum(h => h.Hours)
};
OK i find solution by removing hours from group:
LINQ:
var query = from hours in _hourRepository.GetAll()
join proj in _projectRepository.GetAll() on hours.ProjectId equals proj.Id
where hours.PeopleId == personId
group hours by new { proj.Id, proj.Name, proj.Flag } into g
select new PopleProjectsSumDto
{
Id = g.Key.Id,
Name = g.Key.Name,
Flag = g.Key.Flag,
Hours = g.Sum(h => h.Hours)
};

Query syntax in entity framework

I'm doing a query (see below), but I do not know how to retrieve all data from a select.
var model = new dbContext();
var query = from mp in model.matiere_premiere join req in (from stk in model.stock_mp
join ms in model.matiere_premiere
on stk.matiere_premiere_code equals
ms.code
where stk.date <= DateTime.Today
orderby stk.date descending
select new new { stk.qte, stk.matiere_premiere_code })
on mp.code equals req.matiere_premiere_code
group mp by new { mp.code } into grp
orderby grp.Key
select new
{
grp.Key,
grp.First().designation,
grp.Last().frns
};
The equivalent sql query is:
SELECT matiere_premiere.code,matiere_premiere.designation,
"matiere_premiere.unite, matiere_premiere.frns ,IF(ISNULL(REQ.qte), '0.00', REQ.qte) AS qte
FROM matiere_premiere LEFT JOIN (SELECT qte,matiere_premiere_code FROM stock_mp
JOIN matiere_premiere ON matiere_premiere.code = matiere_premiere_code
WHERE DATE <= CURRENT_DATE() ORDER BY DATE DESC)
AS REQ ON REQ.matiere_premiere_code = matiere_premiere.code
GROUP BY matiere_premiere.code ORDER BY matiere_premiere.code
it's simple, the group is also an enumerator, so you should return
select grp;
then, for each group, you can do a foreach of the values
foreach(var group in query)
{
Console.WriteLine("Key: " + group.Key);
foreach(var v in group)
{
Console.WriteLine("Value: " + v.Property);
}
}

What is the equivalent DISTINCT(sql server) in the Linq

I have a Table(Send) with columns(Id, UserId,SendDate) and another table(Receive) with columns(Id,SendId,UserName).
I want show all records in SendTable with all RecieveUserName.
for example.
(Send)
1 1 2013
2 2 2013
(Recieve)
1 1 Jack
2 1 Ema
3 2 Alex
4 2 Sara
Result
1 1 2013 Jack, Ema
2 2 2013 Alex, Sara
I use this query in SqlServer (The DISTINCT keyword eliminates duplicate rows from the results of a SELECT statement)
SELECT DISTINCT c2.Id,
(SELECT STR( UserName )+ ','
FROM dbo.Reciver c1
WHERE c1.SendId = c2.id FOR XML PATH('')) Concatenated, c2.SendDate, c2.UserId
FROM dbo.Send AS c2 INNER JOIN
dbo.Reciver ON c2.Id = dbo.Reciver.SendId
How do this query in Linq?
Distinct is also available in LINQ.
For example
public class Product
{
public string Name { get; set; }
public int Code { get; set; }
}
Product[] products = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 },
new Product { Name = "apple", Code = 10 },
new Product { Name = "lemon", Code = 9 } };
var lstDistProduct = products.Distinct();
foreach (Product p in list1)
{
Console.WriteLine(p.Code + " : " + p.Name);
}
Will return all rows.
var list1 = products.DistinctBy(x=> x.Code);
foreach (Product p in list1)
{
Console.WriteLine(p.Code + " : " + p.Name);
}
will return 9 and 4
It doesn't seem to me that you need to use Distinct in this Linq query. Assuming you have the relationships between tables set up on your linq datacontext, you can do something like this:
var result = from s in context.Send
select new {
id = s.Id,
userId = s.UserId,
date = s.SendDate,
users = s.Receive.Select(u => u.UserName)
}
Note: users will an IEnumerable<String> - you can use string.Join() on the client to join the names into a string.
Update
To return users as a string to first need to 'switch' to Linq To Objects by calling AsEnumerable() or ToList() and the Linq to Sql query.
var output = from s in result.AsEnumerable()
select new {
id = s.id,
userId = s.userId,
date = s.date,
users = string.Join(", ", s.users)
}
Also see Gert Arnolds answer for a good explanation.
What you want can only be done in two steps. Not because of the DISTINCT, but because of the FOR XML. The C# equivalent of the latter is String.Join(), but you can't use that in a linq to entities statement directly. So you must collect the required data first, then switch to linq to objects (by applying AsEnumerable) and then do the concatenation and distinct:
db.Sends
.Where(s => s.Receivers.Any())
.Select(s => new {
s.Id,
Concatenated = s.Receivers.Select(r => r.UserName)
s.SendDate,
s.UserId
})
.AsEnumerable()
.Select(x => new {
s.Id,
Concatenated = String.Join(", ", x.Concatenated)
s.SendDate,
s.UserId
})
.Distinct()

SQL to LINQ Group by convertion

I have an SQL statement and I want to convert it to LINQ. The problem now is that I don't know how to group by it in LINQ.
Here is the code.
In SQL
select plp.ProspectsListID, p.Prospect_PII_Key
from ProspectListProspect plp
join Prospects p
on p.ProspectsID = plp.ProspectsID
group by plp.ProspectsListID,p.Prospect_PII_Key
In LINQ
var list1 = from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
select new
{
ProspectID = plp.ProspectsListID,
Prospect_PII_Key = p.Prospect_PII_Key
};
thanks
Jason
tyr this
var list1 = from item in
(
from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
select new
{
ProspectID = plp.ProspectsListID,
Prospect_PII_Key = p.Prospect_PII_Key
}
)
group item by new {item.ProspectID ,item.Prospect_PII_Key } into grp
select new
{
ProspectID = grp.ProspectsListID,
Prospect_PII_Key = grp.Prospect_PII_Key
}
;
Check this
var list1 = from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
Group By Key = New With {plp.ProspectsListID,p.Prospect_PII_Key} Into Group
Select Group;
var list1 = from plp in GetDataContext.SQLDataContext.GetTable<DataAccess.ProspectListProspect>()
join p in GetDataContext.SQLDataContext.GetTable<DataAccess.Prospect>()
on plp.ProspectsID equals p.ProspectsID
group p by new {plp.ProspectsListID,p.Prospect_PII_Key} into g
select new
{
ProspectID = g.Key.ProspectsListID,
Prospect_PII_Key = g.Key.Prospect_PII_Key
};