Dapper selecting nested objects - c#

My SQL looks like
Select TOP 3 o.OrderId,
o.Total,
od.Quantity,
od.ItemDescription,
os.OrderStatusDescription,
os.OrderStatusID
From dbo.Orders o
INNER JOIN dbo.OrderStatuses os ON os.OrderStatusID = o.OrderStatusID
INNER JOIN dbo.OrderDetails od ON od.OrderID = o.OrderID
Where o.CustomerId = 100 order by OrderDate desc;
I have my class on c# side as below, i have three tables on db side as well.
i am trying to see if i can use dapper to map 3 tables into one object Order withouty having to do multiple select querys.
i need top 3 rows from Order Table and its child tables loaded. OrderDetail can have n rows for 1 orderId.
How can i selected nested object with 1 look up using dapper?
class Order{
int OrderId {get;set;}
decimal Total {get;set;}
List<OrderDetail> Details {get;set;}
OrderStatus Status {get;set;}
}
class OrderDetail
{
int OrderLineId {get;set;}
int OrderId {get;set;}
string ItemDescription {get;set;}
int Quantity {get;set;}
}
class OrderStatus
{
int OrderStatusID {get;set;}
string OrderStatusDescription {get;set;}
}
this is what i have tried so far but not successful
sqlConnection.Open();
IEnumerable orders = sqlConnection
.Query<Order>(
#"select Order.*, OrderDetail.*
from Order join OrderDetail
inner join on Order.OrderId = OrderDetail.OrderId
inner join on Order.OrderStatusID = OrderStatus.OrderId
and Order.CustomerId = 100",
(o, od, os) =>
{
o.Details = od; //this is a List<OrderDetail>
o.Status = os;
return o;
}); //

There are some ways to achieve your case, but for me you can do this by the below code
var sql = #"Select TOP 3 o.OrderId,
o.Total,
os.OrderStatusID,
os.OrderStatusDescription,
od.OrderLineId,
od.Quantity,
od.ItemDescription
From dbo.Orders o
INNER JOIN dbo.OrderStatuses os ON os.OrderStatusID = o.OrderStatusID
INNER JOIN dbo.OrderDetails od ON od.OrderID = o.OrderID
Where o.CustomerId = 100 order by OrderDate desc;";
sqlConnection.Open();
var lookupOrders = new Dictionary<int,Order>();
var oders = sqlConnection.Query<Order, OrderStatus, OrderDetails, Order>(sql,
(o, os, od) =>
{
Order order;
if(!lookupOrders.ContainsKey(o.OrderId)){
lookupOrders.Add(o.OrderId, o);
order = o;
order.Details = new List<OrderDetail>();
}
else {
order = lookupOrders[o.OrderId];
}
order.Details.Add(od);
order.Status = os;
return order;
}, splitOn: "OrderId, OrderStatusID, OrderLineId"
).Distinct();

Related

Inner join statement in bind variables

I use bind variables to get data from the SQL tables.
The code:
string commandText = string.Format("SELECT {0} FROM {1} WHERE {2} ORDER BY {3}", fields, from, whereStr, orderBy);
DbCommand command = GetSqlCommandWrapper(commandText);
int index = 0;
foreach (var item in whereParams)
{
command.Parameters.Add(new OracleParameter(item, whereParamsBy[index++]));
}
DataTable db = new DataTable();
DataSet dataSet = null;
dataSet = CurrentDatabase.ExecuteDataSet(command);
The CommandText:
fields = "TableA.*";
from = "TableA INNER JOIN TableB ON TableA .id = TableB.id";
whereStr = "TableA .id > 10";
orderBy = "TableA .id, TableB .id";
Everything works fine until I have to get data from 2 tables like the query:
select * from a inner join b on a.id = b.id where....
Someone can tell me how to do it?
Thanks in advance
The overall approach is not very nice, but in terms of getting what you want, this should do it.
fields = "*";
from = "TableA AS a INNER JOIN TableB AS B ON a.id = b.id";
whereStr = "a.id > 10";
orderBy = "a.id, b.id";
Set your input parameters to that, or just paste it in before the code you gave us and it will produce the command SELECT * FROM TableA AS a INNER JOIN TableB AS B ON a.id = b.id WHERE a.id > 10 ORDER BY a.id, b.id
Please note that orderBy = "a.id; DROP TABLE TableA;"; is a scary prospect

c# SQL Query error when trying to join a table

I am having diffculties joining a table in my code. Below you can see my code, I am getting an error on the join 2 table trying to connect my parts table.
if (query.Any()) // Check if REG is in the Database
{
int carID = query.FirstOrDefault().Id;
string carRegg = query.FirstOrDefault().regNo;
string carMake = query.FirstOrDefault().Make;
string carModel = query.FirstOrDefault().Model;
var test = (from a in dbC.Cars
where a.Id == carID
join b in dbC.Services on a.Id equals b.ServiceWrkNo
join c in dbC.PartsUseds on b.ServiceWrkNo equals c.PartsUsedNo
join d in dbC.Parts on c.PartsUsedNo equals d.PartName
select new
{
serviceNum = b.ServiceWrkNo,
PartNo = c.PartsUsedNo,
replacedParts = d.PartName
}).ToList();
the database I created from a model first method is below.
Your join do seems a little bit off -- could you try the join with the following columns
var test = (from a in dbC.Cars
where a.Id == carID
join b in dbC.Services on a.Id equals b.CarId
join c in dbC.PartsUseds on b.ServiceWrkNo equals c.ServiceServiceWrkNo
join d in dbC.Parts on c.PartsPartNo equals d.PartNo
select new
{
serviceNum = b.ServiceWrkNo,
PartNo = c.PartsUsedNo,
replacedParts = d.PartName
}).ToList();

Correct sql to linq query

I'm having difficulty converting this sql query to a linq query. I'm trying to select all my orders with the order details attached to that order. In sql the query is correct. When I write it in linq is when everything goes haywire. Here is my code:
var result = from order in orders
join orderDetail in orderDetails
on order.OrderID equals orderDetail.OrderID
select new OrderVm
{
OrderId = order.OrderID,
OrderDetails = order.Order_Details.Select(x =>
new OrderDetailVm
{
OrderId = orderDetail.OrderID,
UnitPrice = orderDetail.UnitPrice,
Quantity = orderDetail.Quantity,
ProductId = orderDetail.ProductID
})
};
return result.ToList();
that produces this result
but in sql if I write
select
o.OrderID,
o.CustomerID,
od.UnitPrice,
od.Quantity,
od.productid,
p.ProductName
from Orders o
inner join [Order Details] od
on o.OrderID = od.OrderID
inner join Products p
on p.ProductID = od.ProductID
where o.OrderID = 10248
my expected out come is
It looks like from the way that you are using Order_Details in the nested object that the join already exists and that the join you are using is redundant.
var result = from order in orders
select new OrderVm
{
OrderId = order.OrderID,
OrderDetails = order.Order_Details.Select(x =>
new OrderDetailVm
{
OrderId = x.OrderID,
UnitPrice = x.UnitPrice,
Quantity = x.Quantity,
ProductId = x.ProductID
})
};

In LINQ using Entity Framework, how to simplify the query if the table doesn't have foreign key relation?`

I have a table Invoice and it has one column AssetId; and it's related to two other tables Insurer and Customer but with this column (AssetId) I need to find one of the table values in which main table column is related.
I wrote a Linq query, it seems complex when too many records available.
Note: AssetId is not a foreign key.
My query is:
var query = (from c in _invoiceRepository.Table
join d in _CustomerRepository.Table
on c.AssetID equals d.CustomerID
where c.CompanyID == companyID && (c.Deleted == false || c.Deleted == null)
select new
{
InvoiceID = c.InvoiceID,
ApplyTo = c.ApplyTo,
CustomerID = c.AssetID,
ContactID = c.ContactID,
Name = d.FullName,
InvoiceNo = c.InvoiceNo,
InvoiceDate = c.InvoiceDate,
TotalExGST = c.TotalExGST,
GST = c.GST,
TotalIncGST = c.TotalIncGST,
QuickInvoiceDesc = c.QuickInvoiceDesc,
companyID = c.CompanyID,
CreatedDate = c.CreatedDate
}).Union
(from c in _invoiceRepository.Table
join d in _insurerRepository.Table
on c.AssetID equals d.InsurerID
where c.CompanyID == companyID && (c.Deleted == false || c.Deleted == null)
select new
{
InvoiceID = c.InvoiceID,
ApplyTo = c.ApplyTo,
CustomerID = c.AssetID,
ContactID = c.ContactID,
Name = d.Name,
InvoiceNo = c.InvoiceNo,
InvoiceDate = c.InvoiceDate,
TotalExGST = c.TotalExGST,
GST = c.GST,
TotalIncGST = c.TotalIncGST,
QuickInvoiceDesc = c.QuickInvoiceDesc,
companyID = c.CompanyID,
CreatedDate = c.CreatedDate
});

How do I change this query to linq to sql?

Query:
select emp.empname as Name, dep.depname as Department
from Employee as emp
inner join Department as dep on emp.depid=dep.depid
where emp.id='2'
How can I change this to linq to sql?
var id = 2;
var qry = from e in db.Employees
where e.Id == id
select new {
Name = e.EmpName,
Department = e.Department.DepName
};
(assumes the parent-association between employee and department is defined in the DBML)
and if you expect exactly one such:
var record = qry.Single();
Console.WriteLine(record.Name);
Console.WriteLine(record.Department);
Approximately:
from e in dc.Employee
join d in dc.Department on e.depid equals d.depid
where e.id == '2'
select new
{
Name = e.empname,
Department = d.depname
}
This is why LINQ is so great: there is no reason to even join with the Departments table to get it to work:
from employee in db.Employees
where employee.id == 2
select new
{
Name = employee.empname,
Department = employee.Department.depname
};

Categories

Resources