Convert Linq to SQL - asp.net

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

Related

How do i get the Count of InventSerialId from InventDim

How do i create a query or using select to get the count of InventSerialId base on a given Itemid, InventLocationId and where the inventSum.PhysicalInvent > 0 or inventSum.Picked > 0.
This is not directly possible using X++.
Consider:
static void _TestDim(Args _args)
{
ItemId itemId = '123';
InventSum inventSum;
InventDim inventDim;
Query q = new Query();
QueryBuildDataSource ds = q.addDataSource(tableNum(InventSum), 's');
QueryRun qr;
;
// ds.addRange(fieldNum(InventSum,ItemId)).value(queryValue(itemId));
ds.addRange(fieldNum(InventSum,Closed)).value(queryValue(NoYes::No));
ds.addGroupByField(fieldNum(InventSum,ItemId));
ds.addSelectionField(fieldNum(InventSum,PhysicalInvent),SelectionField::Sum);
ds.addSelectionField(fieldNum(InventSum,Picked),SelectionField::Sum);
q.addHavingFilter(ds, fieldStr(InventSum,PhysicalInvent), AggregateFunction::Sum).value('>0');
// q.addHavingFilter(ds, fieldStr(InventSum,Picked), AggregateFunction::Sum).value('((s.Picked >0)||(s.PhysicalInvent>0))'); // This is not allowed
ds = ds.addDataSource(tableNum(InventDim), 'd');
ds.joinMode(JoinMode::InnerJoin);
ds.relations(true);
ds.addGroupByField(fieldNum(InventDim,InventSerialId));
ds.addRange(fieldNum(InventDim,InventSerialId)).value('>""');
info(q.dataSourceNo(1).toString());
qr = new QueryRun(q);
while (qr.next())
{
inventSum = qr.getNo(1);
inventDim = qr.getNo(2);
info(strFmt('%1 %2: %3 %4', inventSum.ItemId, inventDim.InventSerialId, inventSum.PhysicalInvent, inventSum.Picked));
break;
}
}
Here you aggreate PhysicalInvent and picked, and you can apply a having-filter using the query method addHavingFilter.
However, you cannot have that combined with another having-filter using a SQL or-statement.
If you try with a query expression, you will get a run-time error.
What you can do is create two views with each filter, then combine them using a union view. This is tricky but doable.
The first should select positive PhysicalInvent and the second should select PhysicalInvent == 0 and positive Picked.

Can SQLite return the id when inserting data?

I'm using sqlite3.exe to execute queries against my DB, using the following code.
public static string QueryDB(string query)
{
string output = System.String.Empty;
string error = System.String.Empty;
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = "C:\\sqlite\\sqlite3.exe";
startInfo.Arguments = "test.db " + query;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
try
{
using(System.Diagnostics.Process sqlite3 = System.Diagnostics.Process.Start(startInfo))
{
output = sqlite3.StandardOutput.ReadToEnd();
error = sqlite3.StandardError.ReadToEnd();
sqlite3.WaitForExit();
}
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex.ToString());
return null;
}
return output;
}
I'm inserting data into a table, and I'd like it to return the id of the inserted data. Is there a way to get SQLite to do this?
For example, my query might look like this "INSERT INTO mytable (some_values) VALUES ('some value');". After this query is run, I'd like output to contain the rowid of the inserted data. Is there any way to do this (a command line switch, etc.)?
A possible workaround, is to run two commands against the DB. First insert the data, then get the last inserted row id. In which case, the query would look like this "\"INSERT INTO mytable (some_values) VALUES ('some value'); SELECT last_insert_rowid();\""
You should not use max(id) or similar function in DB.
In this specific case it can work, under the condition that you use ONE connection and ONE thread to write data to DB.
In case of multiple connections you can get wrong answer.
From version SQLite 3.35.0 it supports returning close in the insert statement (SQLite Returning Close)
create table test (
id integer not null primary key autoincrement,
val text
);
insert into table test(val) values (val) returning id;
Would you consider this:
select max(id) from your_table_name;
or embedded function last_insert_rowid()?

how to write inline linq query from sql query

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

Displaying LINQ query results in a DataGridView with a DataTable

I have a function which contains a LINQ query and returns the results as a DataTable. I'm having trouble using the returned DataTable to populate a DataGridView. The query should be returning some data, but the table looks to be coming back empty. My function is as follows:
public static DataTable GetEmployeeTimesheets(int employeeId)
{
DataTable table = new DataTable();
using (PTMS_DataEntities entities = new PTMS_DataEntities())
{
var timesheets = from timesheet in entities.Timesheets
join timesheetTask in entities.Timesheet_Task
on timesheet.Id equals timesheetTask.Timesheet_Id
join task in entities.Tasks
on timesheetTask.Task_Id equals task.Id
join project in entities.Projects
on task.Project_Id equals project.Id
join department in entities.Departments
on project.Department_Id equals department.Id
where timesheet.Employee_Id == employeeId
select new
{
date = timesheet.Date,
taskName = task.Name,
projectName = project.Name,
projectDesc = project.Description,
departmentName = department.Name,
taskEstimatedHours = task.Estimated_Hours,
timesheetHours = timesheetTask.Hours
};
table.Columns.Add("date");
table.Columns.Add("taskName");
table.Columns.Add("projectName");
table.Columns.Add("projectDesc");
table.Columns.Add("departmentName");
table.Columns.Add("taskEstimatedHours");
table.Columns.Add("timesheetHours");
foreach (var item in timesheets)
{
table.Rows.Add(item.date, item.taskName, item.projectName,
item.projectDesc, item.departmentName, item.taskEstimatedHours,
item.timesheetHours);
}
}
return table;
}
The code populating the DataGridView is as follows:
TimesheetGrid.DataSource = EmployeeManager.GetEmployeeTimesheets(employeeId);
TimesheetGrid.DataBind();
Am I doing something wrong in the function / LINQ query itself, or am I just not populating the DataGridView correctly?

how to group a query in linq to Entity

I am using linq to Entity to retrieve data from to different tables by joining them, but I also want to group them by the field problemDesc in order to get rid of unnecessary duplicate entries for the same problem.
here is the code:
using (AssistantEntities context = new AssistantEntities())
{
var problems = context.tblProblems;
var customers = context.tblCustomers;
var query =
from problem in problems
join customer in customers
on problem.CustID equals customer.custID
where problem.IsActive == true
orderby customer.isMonthlyService == true descending
select new
{
problemID = problem.problemID,
ProblemCreateDate = problem.ProblemCreateDate,
CustID = problem.CustID,
name = customer.name,
isMonthlyService = customer.isMonthlyService,
StationName = problem.StationName,
problemDesc = problem.problemDesc,
LogMeIn = problem.LogMeIn
};
return query.ToList();
}
I am doing query.toList() in order to use that list in a gridview as a dataSource.
and if it possible, also add a field that count the duplicate problems.
You have plenty of examples in the following link.
LINQ - Grouping Operators

Resources