I need get the Max from column using Entity Framework without use GroupBy.
var query= from r in table1
join rt in table2 on r.ID equals rt.ID
where rt.DateStart >= dtS && rt.DateEnd < dtE
select new datart { ID = rt.ID, Start = rt.DateStart, End = rt.DateEnd }
I want make something like this:
var query= from r in table1
join rt in table2 on r.ID equals rt.ID
where rt.DateStart >= dtS && rt.DateEnd < dtE
select new datart { ID = rt.ID, Start = Min.(rt.DateStart), End = Max.(rt.DateEnd) }
I don't understand your question, but I guess using OrderByDescending + First can help you:
var query= from r in table1
join rt in table2 on r.ID = r.rt.ID
where rt.DateStart >= dtS && rt.DateEnd < dtE
select new datart { ID = rt.ID, Start = rt.DateStart };
var result =
query
.OrderByDescending(t => t.DateStart)
.First();
Related
I have a list of ids, that I then have multiple IQueryables that at the end I am joining to return my results. However some of these queries could have multiple records for that particular ID and I only need 1 record per ID from my set of x IDs. For example there could be 1 Name record, 3 Addresses, 2 Emails, 4 Phones for a single ID, but I only need 1 of each, does not matter which if multiple exist.
var clientNames = (
from n in db.Names
join cnl in db.ClientNameLinks on n.name_id equals cnl.name_id
where request.Ids.Contains(cnl.client_id)
&& n.name_id > 0
&& n.nametype_id != null
select new
{
n.display_name,
cnl.client_id
});
var clientAddresses = (
from a in db.Addresses
join cal in db.ClientAddressLinks on a.address_id equals cal.address_id
where request.Ids.Contains(cal.client_id)
&& a.address_id > 0
select new {
a.display_address,
cal.client_id
});
var clientEmails = (
from e in db.Emails
join cel in db.ClientEmailLinks on e.email_id equals cel.email_id
where request.Ids.Contains(cel.client_id)
&& e.email_id > 0
select new {
e.email_address,
cel.client_id
});
var clientPhones = (
from p in db.Phones
join cpl in db.ClientPhoneLinks on p.phone_id equals cpl.phone_id
where request.Ids.Contains(cpl.client_id)
&& p.phone_id > 0
select new {
p.phone_num,
cpl.client_id
});
var rows = await (
from n in clientNames
join a in clientAddresses on n.client_id equals a.client_id into n_a
from na in n_a.DefaultIfEmpty() //LEFT JOIN
join e in clientEmails on n.client_id equals e.client_id into n_e
from ne in n_e.DefaultIfEmpty() //LEFT JOIN
join ph in clientPhones on n.client_id equals ph.client_id into n_p
from np in n_p.DefaultIfEmpty() //LEFT JOIN
select new PiiDiamondClient
{
ClientId = n.client_id,
DisplayName = n.display_name,
DisplayAddress = na.display_address,
EmailAddress = ne.email_address,
PhoneExtension = np.phone_ext,
PhoneNumber = np.phone_num
}).Distinct().ToListAsync();
return rows.OrderBy(x => x.ClientId).ToList();
Your last query can be rewritten in the following way. It will exactly get one record from JOIN which can multiply result set.
var query =
from n in clientNames
from a in clientAddresses.Where(a => n.client_id == a.client_id)
.Take(1).DefaultIfEmpty() //OUTER APPLY or LEFT JOIN on ROW_NUMBER query
from e in clientEmails.Where(e => n.client_id == e.client_id)
.Take(1).DefaultIfEmpty() //OUTER APPLY or LEFT JOIN on ROW_NUMBER query
from ph in clientPhones.Where(ph => n.client_id == ph.client_id)
.Take(1).DefaultIfEmpty() //OUTER APPLY or LEFT JOIN on ROW_NUMBER query
select new PiiDiamondClient
{
ClientId = n.client_id,
DisplayName = n.display_name,
DisplayAddress = a.display_address,
EmailAddress = e.email_address,
PhoneExtension = ph.phone_ext,
PhoneNumber = ph.phone_num
};
Hi is it possible to translate the below queries into linq ? ...
I am using entity frameworks core and tried to use the stored procedure but it seems like i have to create a model that applies to the metadata of the stored procedure. So i am trying to understand whether this kinda such query can be translated into linq so i don't have to create a separate db model.
SELECT
Stock.stockID ProductID,
stockName ProductName,
categoryName ProductCategory,
typeName ProductType,
sizeName ProductSize,
currentQuantity CurrentQuantity,
standardQuantity QuantityPerBox,
CONVERT(VARCHAR(255),CONVERT(INT,Stock.price)) AvgUnitCost,
CONVERT(VARCHAR(255),CONVERT(INT,x.lastUnitCost)) LastOrderUnitCost,
CONVERT(VARCHAR(10),CONVERT(DATE,x.lastOrderDate)) LastOrderDate
FROM dbo.Stock
LEFT JOIN
(
SELECT stockID,unitPrice lastUnitCost ,orderDate lastOrderDate, ROW_NUMBER() OVER (PARTITION BY stockID ORDER BY orderDate DESC) rn FROM dbo.SalesOrder
JOIN dbo.SalesOrderDetail ON SalesOrderDetail.salesOrderID = SalesOrder.salesOrderID
WHERE customerID = #customerID AND salesStatus = 'S'
) x ON x.stockID = Stock.stockID AND rn = 1
LEFT JOIN dbo.StockCategory ON StockCategory.stockCategoryID = Stock.stockCategoryID
LEFT JOIN dbo.StockType ON StockType.stockTypeID = Stock.stockTypeID
LEFT JOIN dbo.StockSize ON StockSize.stockSizeID = Stock.stockSizeID
WHERE disStock = 0
Almost everything is possible. you just need to be careful with performance.
var query =
from stock in db.Stocks
join x in (
from grp in (
from so in db.SalesOrders
join sod in db.SalesOrderDetails on so.SalesOrderId equals sod.SalesOrderId
where so.CustomerId == customerId && so.SalesStatus == "S"
orderby so.OrderDate descending
select new {
sod.StockId,
LastUnitCost = sod.UnitPrice,
LastOrderDate = so.OrderDate
} into inner
group inner by inner.StockId)
select grp.Take(1)) on x.StockId equals stock.StockId into lastStockSales
from x in lastStockSales.DefaultIfEmpty()
join sc in db.StockCategories on stock.StockCatergotyId equals sc.StockCategoryId into scLeft
from sc in scLeft.DefaultIfEmpty()
join st in db.StockTypes on stock.StockTypeId equals st.StockTypeId into stLeft
from st in stLeft.DefaultIfEmpty()
join ss in db.StockSizes on stock.StockSizeId equals ss.StockSizeId into ssLeft
from ss in ssLeft.DefaultIfEmpty()
where stock.DisStock == 0
select new MyDTO {
ProductId = stock.StockId,
ProductName = stock.StockName,
ProductType = st.TypeName,
ProductSize = ss.SizeName,
CurrentQuantity = stock.CurrentQuantity,
QuantityPerBox = stock.StandardQuantity,
AvgUnitCost = stock.Price,
LastOrderUnitCost = x.LastUnitCost,
LastOrderDate = x.LastOrderDate
};
As you can see is easy to rewrite these queries, I had to change a little bit the logic on how to get the latest sales for a stock item since ROW_NUMBER() OVER (PARTITION... is not supported from a LINQ perspective. Again, you would have to consider performance when rewriting queries.
Hope this helps.
The short:
A simpler way of summing up this question would be, can you apply a conditon on a join in linq?
I have the following sql query:
select cdm.cashID, cdm.DateTimeTillOpened, cdm.DateTimeTillClosed, o.OrderID, o.OrderDate
from CashDrawsMonies cdm
join Orders o on o.OrderDate >= cdm.DateTimeTillOpened
AND o.OrderDate <= cdm.DateTimeTillClosed
join Users u on o.UserID = u.UserID
where u.UserID = 'C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A'
group by cdm.cashID, cdm.DateTimeTillOpened, cdm.DateTimeTillClosed, o.OrderID, o.OrderDate
order by o.OrderDate desc
Alternative SQL#
select *
from CashDrawsMonies cdm
where exists
(
select *
from Orders o
join Users u on o.UserID = u.UserID
where
o.OrderDate >= cdm.DateTimeTillOpened and
o.OrderDate <= cdm.DateTimeTillClosed and
u.UserID = 'C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A'
)
I can convert most queries but on the join in Linq it always asks for an equal keyword and not something like >= or <= which allows me in sql to put a condition on the join. This is what makes me scratch my head as to how do I convert it then?
My linq-To-Entites model in code (c#) is set-up as:
Cache.Model.Orders
Cache.Model.CashDrawMonies
Cache.Model.Users
Appreciate the help.
Attempt 1:
var results = from o in Cache.Model.Orders
from c in Cache.Model.CashDrawMoneys
join u in Cache.Model.Users on o.UserID equals u.UserID
where c.DateTimeTillOpened >= o.OrderDate
&& c.DateTimeTillClosed <= o.OrderDate
select c;
Attempt 2:
var results = from c in Cache.Model.CashDrawMoneys
from o in Cache.Model.Orders
where c.DateTimeTillOpened >= o.OrderDate
&& c.DateTimeTillClosed <= o.OrderDate
group c by new { c.cashID, c.DateTimeTillOpened, c.DateTimeTillClosed, o.OrderID, o.OrderDate, o.UserID } into temp
from t in temp
join u in Cache.Model.Users on t.UserID equals u.UserID
where t.UserID == selectedUser.UserID
select t;
Returns no results .... : S
UPDATE:
I re wrote my sql, the second peiece of sql does exactly what I want know. Just need someone to convert it for me somehow???
SQL Version 2 Converted Using Linqer:
from cdm in db.CashDrawMoneys
where
(from o in db.Orders
join u in db.Users on o.UserID equals u.UserID
where
o.OrderDate >= cdm.DateTimeTillOpened &&
o.OrderDate <= cdm.DateTimeTillClosed &&
u.UserID == new Guid("C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A")
select new {
o,
u
}).FirstOrDefault() != null
select new {
cdm.UserID,
cdm.DateTimeTillClosed,
cdm.DateTimeTillOpened,
cdm.LooseChange,
cdm.Fivers,
cdm.Tens,
cdm.Twenties,
cdm.Fifties,
cdm.IsOpen,
cdm.IsClosed,
cdm.ClosingValue,
cdm.OpeningValue,
cdm.cashID
}
Compiles nbut produces the following error:
"The argument to DbIsNullExpression must refer to a primitive or reference type."
The joins on the first Attempt look about right. But did you turn around the comparison operator?
where c.DateTimeTillOpened **>=** o.OrderDate
&& c.DateTimeTillClosed **<=** o.OrderDate
Update:
You can't create a new object within LINQ2EF as it doesn't know how to translate that to sql.
u.UserID == new Guid("C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A")
You'll have to define the GUID before the linq statement and then use the variable
var gid = new Guid("C3763CC6-D1C5-4EF3-9B83-F7AB3BF8827A")
from cdm in db.CashDrawMoneys
where
(from o in db.Orders
join u in db.Users on o.UserID equals u.UserID
where
o.OrderDate >= cdm.DateTimeTillOpened &&
o.OrderDate <= cdm.DateTimeTillClosed &&
u.UserID == gid
Below is what I managed to get:
var results = from cdm in Cache.Model.CashDrawMoneys
where (from o in Cache.Model.Orders
join u in Cache.Model.Users on o.UserID equals u.UserID
where o.OrderDate >= cdm.DateTimeTillOpened && o.OrderDate <= cdm.DateTimeTillClosed &&
u.UserID == selectedUser.UserID
select o).FirstOrDefault() != null
select cdm;
It's pretty close to what you got and did not have to worry about the guid as it was already created for me as I had a 'selectedUser' object.
The last line could be:
select o).Any()
select cdm;
But I'm not fussed, I get the two variations but Im gonna stick with my first version.
I got this figured out.
No need to answer.
The system says I have to wait 8 hours before answering my own questions. But for now the answer is below:
Here is the answer:
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
join q in Quotes
on h.QuoteID equals q.QuoteID
join a in Agencies
on q.AgencyID equals a.AgencyID
where q.Status == "Inforce" &&
q.LOB == "Vacant" &&
q.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
a.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
MaxHistoryID = g.Max (x => x.h.HistoryID),
comment = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.Comment).FirstOrDefault()
}).ToList();
The key code was:
comment = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.Comment).FirstOrDefault()
We are in the process of converting SQL / Stored Procedures to LINQ to Entities statements. And I can’t figure out the proper syntax for a sub select.
Currently I am converting this SQL:
declare #startDate DateTime
set #startDate = DATEADD(DD, -30, GETDATE())
select * from history where historyid in(
select MAX(h.historyid) as HistoryId
from History h (nolock)
inner join Quote q (nolock) on h.QuoteID = q.QuoteID
inner join Agency (nolock) a on q.AgencyID = a.AgencyID
inner join DC_PLT_EntityRoles er (nolock) on a.AgencyID = er.EntityID
inner join DC_PLT_Roles (nolock) r on er.RoleID = r.RoleID
where
q.Status = 'Inforce'
and q.LOB = 'Vacant'
and q.EffectiveDate > #startDate
and h.Deleted is null --
and h.DeprecatedBy is null --
and h.TransactionStatus = 'Committed'
and r.Name = 'Wholesaler'
group by h.PolicyNumber)
As you can see the code above is made up of two select statements. The main select (select * from history).. And a filter select (select MAX(h.historyid)…)
I got the filter select working (See below):
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
join q in Quotes
on h.QuoteID equals q.QuoteID
join a in Agencies
on q.AgencyID equals a.AgencyID
where q.Status == "Inforce" &&
q.LOB == "Vacant" &&
q.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
a.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
MaxHistoryID = g.Max (x => x.h.HistoryID)
}).ToList();
However I can’t figure out the proper syntax to set up the main select. (Basically getting the records from the History table using the HistoryID from the filter select.)
Any help would be appreciated.
Thanks for your help.
I figured it out, here is the code:
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
.Include("Quote")
.Include("Quote.Agency")
where h.Quote.Status == "Inforce" &&
h.Quote.LOB == "Vacant" &&
h.Quote.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
h.Quote.Agency.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
XMLData = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.XMLData).FirstOrDefault()
}).ToList();
The key logic is:
select new {
XMLData = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.XMLData).FirstOrDefault()
}).ToList();
Gotta love the Nested Query
Can anyone tell me how to write the following query in Entity Framework 4.0? "Blogs" and "Categories" are my entities. The query basically returns me the list of categories and the number of blogs that are in that category.
SELECT b.CategoryId, c.Value, Count(b.Id) AS [Count] FROM dbo.Blogs b
INNER JOIN dbo.Categories c ON b.CategoryId = c.Id
GROUP BY b.CategoryId, c.Value
Thanks in advance.
The following should work (LinqToEntities):
var categories = from c in oc.Categories
select new
{
CategoryId = c.Id,
c.Value,
Count = c.Blogs.Count()
}
This will give you a list of category ids and values and for each category id you get the number of blogs in that category.
EDIT: To give an answer to the question in your comment: this isn't possible in LinqToEntities but you can do it in Entity SQL.
var results = new ObjectQuery<DbDataRecord>(
#"SELECT y, COUNT(y)
FROM MyEntities.Blogs AS b
GROUP BY YEAR(b.CreatedDate) AS y", entities).ToList();
var nrBlogsPerYear = from r in results
select new { Year = r[0], NrBlogs = r[1] };
In the Entity SQL query, you should replace MyEntities with the name of your context.
EDIT: As I just found out through a comment by Craig, grouping by year is possible in L2E so you can write your query like this:
var nrBlogsPerYear = from b in oc.Blogs
group b by b.CreatedDate.Year into g
select new { Year = g.Key, NrBlogs = g.Count() };
If you have navigation properties in your entities, you can do that :
var cats = from c in db.Categories
let count = c.Blogs.Count()
where count > 0
select new
{
CategoryId = c.Id,
Value = c.Value,
Count = count
};
If you prefer to use an explicit join, you can do it like that :
var cats = from c in db.Categories
join b in db.Blogs on c.Id equals b.CategoryId into g
select new
{
CategoryId = c.Id,
Value = c.Value,
Count = g.Count()
};
var query = from p in B.Products
join c in B.Categories on p.CategoryID equals c.CategoryID
orderby c.CategoryName,p.ProductName
select new
{
c.CategoryName ,
p.ProductName,
p.ReorderLevel
};
GridView1.DataSource = query.ToList();
GridView1.DataBind();