how to write inline linq query from sql query - asp.net

the below query is written in sql to select the recent activity of an salesperson based on last activity date
select UDV.User_dailyActivityId,UDV.userId,UDV.[DATE] ActivityDate,UDV.Activity,UDV.Subject
From [SalesTrack].[dbo].[UserDailyActivity] UDV,
(
Select userId,Max([DATE]) ActivityDate from [SalesTrack].[dbo].[UserDailyActivity]
Group by userId
) GPUDV
where udv.userId = GPUDV.userId and UDV.[DATE] = gpudv.ActivityDate
order by udv.userId,UDV.[DATE]
i have to change the above query into linq, i am newbie in linq
i succeed writing the inline query part
var lastgroup=(from ua in db.UserDailyActivities group ua by ua.userId into GPua select new{GPua,ActivityDate=GPua.Max(ua=>ua.date)});
Please help me to finish the whole query

Maybe something like this:
var result=
(
from UDV in db.UserDailyActivity
from GPUDV in
(
from inner in db.UserDailyActivity
group inner by inner.userId into g
select new
{
userId=g.Key,
ActivityDate=g.Max (x =>x.DATE)
}
).Where (w =>w.userId==UDV.userId && w.ActivityDate==UDV.DATE)
select new
{
UDV.User_dailyActivityId,
UDV.userId,
ActivityDate = UDV.[DATE],
UDV.Activity,
UDV.Subject
}
).ToList();
where db is the linq data context

Related

Search using linq and dropdowns

I got about 5 look-a-like linq querys just like this SortPerson() metod. I'm trying to develop a search using dropdowns where a user can select values from the dropdown and returns the values that are true from one or more dropdowns the user has selected to use.
Is there a simpler way to develop this? help would be much appreciated
public void SortPerson()
{
var personId = ddlPerson.SelectedValue;
var data = new MyModelContext();
var documents = from d in data.tblDocuments
join sp in data.tblPersons on d.DocPerson equals sp.PersonId
select d;
if (!String.IsNullOrEmpty(personId))
{
documents = documents.Where(c => c.DocPerson.Equals(personId));
}
rptResult.DataSource = documents.ToList();
rptResult.DataBind();
}
I don't see the point in joining without Where if you still select only one table.
If you want all document in case when Person is not selected, then you can't create much simpler method. You can write it shorter like:
var documents =
from d in data.tblDocuments
join ...
where String.IsNullOrEmpty(personId) || d.DocPerson equals personId
select d;
so you don't need separate if statement.
If you want to use several values from 5 dropdowns and use them as conditions in single query, just add more conditions:
var personId = ddlPerson.SelectedValue;
var someValue = ddlSomeDDL.SelectedValue;
//3 more values from DDL
var documents = from d in data.tblDocuments
join sp in data.tblPersons on d.DocPerson equals sp.PersonId
where (String.IsNullOrEmpty(personId) || sp.PersonId equals personId)
&& (String.IsNullOrEmpty(someValue) || d.SomeColumn equals someValue)
//3 more conditions
select d;

selecting only max clause without group by properties in subquery using Nhibernate

I have SQL query like this:
select * from dbo.table1 where Id in
(
select max(id) as id from dbo.table1 group by prop1, prop2, prop3
)
I want to create NHibernate query which is be able to do this for me. I tried to use QueryOver but it doesn't work. Do you have any suggestions how to do it?
NHibernate supports even this kind of queries. Please, see more in documentation: 15.8. Detached queries and subqueries. We just have to split the query (as in your SQL snippet) into two parts:
inner select
the select with the IN clause
Let's assume, that the dbo.table1 in the Questin is mapped into MyEntity.
To create inner select, let's use the DetachedCriteria
EDIT (extended with the Group by, SqlGroupProjection)
There is an extract of the SqlGroupProjection method:
A grouping SQL projection, specifying both select clause and group by
clause fragments
// inner select
DetachedCriteria innerSelect = DetachedCriteria
.For(typeof(MyEntity))
.SetProjection(
Projections.ProjectionList()
.Add(
Projections.SqlGroupProjection(
" MAX(ID) ", // SELECT ... max(ID) only
" Prop1, Prop2, Prop3", // GROUP BY ... property1, p2...
new string[] {"ID"}, // could be empty, while not used for
new IType[] { NHibernate.NHibernateUtil.Int32 } // transformation
)
)
;
Note: I've provided even the last two paramters, but in this case they could be empty: new string[], new IType[] {}. These are used only for Transformation (materialization from data into entity). And this is not the case, we are just building inner select...
// the select with IN clause
var result = session.CreateCriteria(typeof(MyEntity))
.Add(Subqueries.PropertyIn("ID", innerSelect))
.List<MyEntity>();
Also related could be 15.7. Projections, aggregation and grouping

LINQ - EF join difficulty

I have two tables:
Phase :
long ID
string Name
and another Activity :
long ID
string Name
long PhaseID
I already know the name of the phases and I want to get the activity for those particular phases. Do i add PhaseName to the activity table or do I do it through join in LINQ?
Maybe something like this?
var query = from a in entities.Activities
join p in entities.Phases on a.PhaseId equals p.Id
where p.Name == "Preplanning"
... and here im not sure how to finish this query..
Thanks for your help!
The code that you've provided will use an Inner Join to find all Activities where the Phase with Name "Preplanning" exists.
To finish your query you need to add a select clause.
var query = from a in entities.Activities
join p in entities.Phases on a.PhaseId equals p.Id
where p.Name == "Preplanning"
select a.Name
will return IEnumerable<string> of all activity names.
Just select activity, as you want:
var query = from a in entities.Activities
join p in entities.Phases on a.PhaseId equals p.Id
where p.Name == "Preplanning"
select a;
Here is how query expression should look like:
A query expression must begin with a from clause and must end with a select or group clause. Between the first from clause and the last select or group clause, it can contain one or more of these optional clauses: where, orderby, join, let and even additional from clauses. You can also use the into keyword to enable the result of a join or group clause to serve as the source for additional query clauses in the same query expression.
Same as puzzling image:
With method syntax you don't need to end query with something special:
var query = entities.Phases
.Where(p => p.Name == "Preplanning")
.Join(entities.Activities, p => p.Id, a => a.PhaseId, (p,a) => a);
No need to do a join if you only need data from one of the tables. You can apply a filter instead:
var q = entities.Activities.Where(a =>
entities.Phases.Any(p => a.PhaseId == p.Id && p.Name == "Preplanning"));

Convert Linq to SQL

I have researched on the net and most result are converting from sql to linq and seldom have linq to sql.
this is the code which I want to convert to SQL :
using (CommerceEntities db = new CommerceEntities())
{
try
{
var query = (from ProductOrders in db.OrderDetails
join SelectedProducts in db.Products on ProductOrders.ProductID
equals SelectedProducts.ProductID
group ProductOrders by new
{
ProductId = SelectedProducts.ProductID,
ModelName = SelectedProducts.ModelName
} into grp
select new
{
ModelName = grp.Key.ModelName,
ProductId = grp.Key.ProductId,
Quantity = grp.Sum(o => o.Quantity)
} into orderdgrp where orderdgrp.Quantity > 0
orderby orderdgrp.Quantity descending select orderdgrp).Take(5);
RepeaterItemsList.DataSource = query;
RepeaterItemsList.DataBind();
}
catch (Exception exp)
{
throw new Exception("ERROR: Unable to Load Popular Items - " +
exp.Message.ToString(), exp);
}
}
You can attempt to run the LINQ statement in LinqPad. For examples on how to use LinqPad, check the answer here.
It has a tab to show the generated SQL statement.
Here's an article on logging in LINQ to SQL. It lets you specify a TextWriter to which to send the query.
Basically, you can write something like this:
db.Log = new System.IO.StreamWriter("linq-to-sql.log") { AutoFlush = true };
... where db is your data context.
In SQL you'd write something like this (although the produced code will look a lot different, since it is auto-generated):
SELECT TOP 5 Products.ModelName, Products.ProductID, SUM(OrderDetails.Quantity) qty
FROM OrderDetails
INNER JOIN Products ON OrderDetails.ProductID = Products.ProductID
GROUP BY Products.ProductID, Products.ModelName
HAVING qty > 0
ORDER BY qty DESC

ASP.NET: Linq2SQL: selecting all names matching an id

Got 2 tables: db.Tags (ID, TagName) and db.Names (ID, Name, TagID).
I want to fetch all db.Tags rows, and all the Names matching the TagID.
So it will look like
ID - TagName - Names
1 - tag1 - name1, name2, name3
2 - tag2 - name4, name5, name6
Is this possible in one (long) linq query?
or do I have to get all the tags, then do foreach tag, get all the names, then do foreach names to put them in a one long string..
Thanks in advance!
EDIT:
Okay see my comment on the second answer (first one up..), this is what i tried but i get some errors in compiler:
var tags =
from t in db.Tags
orderby t.Priority ascending
select new {
t.ID,
t.Name,
t.Priority,
Places = String.Join(", ",
(from p in db.Places
join o in db.TagToPlaces on new {
p.ID,
t.ID
}
equals new {
o.PlaceId,
o.TagId
}
select p.Name
).ToArray()
)
}
);
I think this is what you're after:
var query =
from t in db.Tags
select new
{
t.ID,
t.TagName,
Names = String.Join(", ",
(from n in db.Names
where n.TagID == t.ID
select n.Name)
.ToArray()),
};
With this I get the same sort of output that you gave in your question. I also understood that you want to output the tag id and name even when there are no associated name records - my query does that.
Now depending on if you're using EF or LINQ-to-SQL or something else you may need to add .ToArray() to the db.Tags & db.Names references to force the database query to occur.
If you have a large number of tag records you'll find you have a large number of queries going to the database. You could make this change to reduce it to only two queries:
var tags = db.Tags.ToArray();
var names = db.Names.ToArray();
var query =
from t in tags
select new
{
t.ID,
t.TagName,
Names = String.Join(", ",
(from n in names
where n.TagID == t.ID
select n.Name)
.ToArray()),
};
Now you just need to make sure that your data fits into memory - but it sounds like it should. I hope this helps.
Since the concat is a pain in TSQL, I would query the 3 values "as is", and format from there:
var list = (from tag in db.Tags
join name in db.Names
on tag.ID equals name.TagId
orderby tag.ID
select new { tag.ID, tag.TagName, name.Name }).ToList();
for example, if I wanted the names by tag-id, I could do:
var namesByTag = list.ToLookup(row => row.ID, row => row.Name);
(or whatever else you choose)

Resources