I am trying to make a linq query to execute this query. The column Additional Data is nvarchar(20) - so linq is reading it as a string
this works fine in SSMS
select SUM(CAST(AdditionalData as smallmoney)) from TransTable
where ActionID = #actID and UserID = uID;
this is my failed attempt at a linq version ( Decimal.Parse() can not be converted to sql from linq i guess)
(from a in Context.TransTable
where a.ActionID == action.ActionID && a.UserID == (long)userId
select decimal.Parse(a.AdditionalData)).Sum();
If the result set isn't too large you could parse the value on the client.
decimal value;
var sum = (from a in Context.TransTable
where a.ActionID == action.ActionID && a.UserID == (long)userId
select a.AdditionalValue).ToList().
Select(x => decimal.TryParse(x, out value) ? value : 0).Sum();
Related
I try to convert SQL to LINK query
I try this
SQL query
Select name, count(*) from tblVehicles
WHERE MID = 23065 and name<> '' Group By name
LINQ query
var re = (from vehvoila in DB.tblVehicles
where vehvoila.MID='23065' && vehvoila.name
group vehvoila by new{vehvoila.name} into g
select new
{
g.Key.name,
cnt=g.Select(t=>t.name).Count()
});
How I use <> in LINQ ?
What could work for you is
where vehvoila.MID == "23065" && !(vehvoila.name == null || vehvoila.name == "")
or just
where vehvoila.MID == "23065" && vehvoila.name != ""
String.IsNullOrEmpty in not supported in Linq-SQL:
Method 'Boolean IsNullOrEmpty(System.String)' has no supported translation to SQL.
I have the following query:
SELECT COUNT(1)
FROM Warehouse.WorkItems wi
WHERE wi.TaskId = (SELECT TaskId
FROM Warehouse.WorkItems
WHERE WorkItemId = #WorkItemId)
AND wi.IsComplete = 0;
And since we are using EF, I'd like to be able to use the Linq functionality to generate this query. (I know that I can give it a string query like this, but I would like to use EF+Linq to generate the query for me, for refactoring reasons.)
I really don't need to know the results of the query. I just need to know if there are any results. (The use of an Any() would be perfect, but I can't get the write code for it.)
So... Basically, how do I write that SQL query as a LINQ query?
Edit: Table Structure
WorkItemId - int - Primary Key
TaskId - int - Foreign Key on Warehouse.Tasks
IsComplete - bool
JobId - int
UserName - string
ReportName - string
ReportCriteria - string
ReportId - int - Foreign Key on Warehouse.Reports
CreatedTime - DateTime
The direct translation could be something like this
var result = db.WorkItems.Any(wi =>
!wi.IsComplete && wi.TaskId == db.WorkItems
.Where(x => x.WorkItemId == workItemId)
.Select(x => x.TaskId)
.FirstOrDefault()));
Taking into account the fact that SQL =(subquery), IN (subquery) and EXISTS(subquery) in nowadays modern databases are handled identically, you can try this instead
var result = db.WorkItems.Any(wi =>
!wi.IsComplete && db.WorkItems.Any(x => x.WorkItemId == workItemId
&& x.TaskId == wi.TaskId));
Turns out that I just needed to approach the problem from a different angle.
I came up with about three solutions with varying Linq syntaxes:
Full method chain:
var q1 = Warehouse.WorkItems
.Where(workItem => workItem.TaskId == (from wis in Warehouse.WorkItems
where wis.WorkItemId == workItemId
select wis.TaskId).First())
.Any(workItem => !workItem.IsComplete);
Mixed query + method chain:
var q2 = Warehouse.WorkItems
.Where(workItem => workItem.TaskId == Warehouse.WorkItems
.Where(wis => wis.WorkItemId == workItemId)
.Select(wis => wis.TaskId)
.First())
.Any(workItem => !workItem.IsComplete);
Full query:
var q3 = (from wi in Warehouse.WorkItems
where wi.TaskId == (from swi in Warehouse.WorkItems
where swi.WorkItemId == workItemId
select swi.TaskId).First()
where !wi.IsComplete
select 1).Any();
The only problems with this is that it comes up with some really jacked up SQL:
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [Warehouse].[WorkItems] AS [t0]
WHERE (NOT ([t0].[IsComplete] = 1)) AND ([t0].[TaskId] = ((
SELECT TOP (1) [t1].[TaskId]
FROM [Warehouse].[WorkItems] AS [t1]
WHERE [t1].[WorkItemId] = #p0
)))
) THEN 1
ELSE 0
END) AS [value]
You can use the Any() function like so:
var result = Warehouse.WorkItems.Any(x => x.WorkItemId != null);
In short, you pass in your condition, which in this case is checking whether or not any of the items in your collection have an ID
The variable result will tell you whether or not all items in your collection have ID's.
Here's a helpful webpage to help you get started with LINQ: http://www.dotnetperls.com/linq
Subquery in the original SQL was a useless one, thus not a good sample for Any() usage. It is simply:
SELECT COUNT(*)
FROM Warehouse.WorkItems wi
WHERE WorkItemId = #WorkItemId
AND wi.IsComplete = 0;
It looks like, since the result would be 0 or 1 only, guessing the purpose and based on seeking how to write Any(), it may be written as:
SELECT CASE WHEN EXISTS ( SELECT *
FROM Warehouse.WorkItems wi
WHERE WorkItemId = #WorkItemId AND
wi.IsComplete = 0 ) THEN 1
ELSE 0
END;
Then it makes sense to use Any():
bool exists = db.WorkItems.Any( wi => wi.WorkItemId == workItemId & !wi.IsComplete );
EDIT: I misread the original query in a hurry, sorry. Here is an update on the Linq usage:
bool exists = db.WorkItems.Any( wi =>
db.WorkItems
.SingleOrDefault(wi.WorkItemId == workItemId).TaskId == wi.TaskId
&& !wi.IsComplete );
If the count was needed as in the original SQL:
var count = db.WorkItems.Count( wi =>
db.WorkItems
.SingleOrDefault(wi.WorkItemId == workItemId).TaskId == wi.TaskId
&& !wi.IsComplete );
Sorry again for the confusion.
I have a Linq Query that works well but I need to write the SQL Query
Can Anybody help me write it?
this query will search the database foreach a.h and a.HV in the view with the filters of time and model and in the end it checks the option Filter.M that if it is selected it will search for all the data selected in this DropDownCheckBoxes`
How can i write the this where and select part in SQL command?
ret1 = (from a in View
where
a.LastRefreshTime>=Filter.From && a.LastRefreshTime<=Filter.To && a.ModelCode == mdlCode &&
Filter.PN.Select(epn => epn.Substring(0, 11)).Contains(a.H) &&
Filter.PN.Select(epn => epn.Substring(14, 2)).Contains(a.HV)
select new RData
{
v = a.v,
Date = a.LastRefreshTime,
UserId = a.UserId,
M = a.Name,
}).Distinct().AsQueryable();
ret = ret1.Where(nr =>
Filter.M == null || !Filter.M.Any() || Filter.M.Contains(nr.M)
).ToList();
Here's a start for you
select a.v v,
a.LastRefreshTime "Date",
a.UserId,
a.Name
from a
where a.LastRefreshTime>= arg_filter_from
and a.LastRefreshTime<= arg_filter_to
and a.ModelCode = arg_mdlCode
.
.
.
In this query you'll need to replace 'arg_...' with the appropriate values or arguments you want.
Contains is roughly equivalent to "IN" in SQL. For example:
where a.Name in ('jim', 'bob', 'joe')
In can also be used with a subselect which is roughly what I think Filter.PN.Select is doing though I'm not a linq expert. Example:
where a.H in (Select foo from PN_Table)
Or simpler example continuing on the my previous name example:
where a.Name in (select first_name from table)
If we supposed that the Filter.PN list represent a table FilterPN in your sql database, that will be your converted code for the first linq query
select distinct a.v, a.LastRefreshTime, a.UserId, a.Name
from [view] a
where a.LastRefreshTime>= 'Filter.From' and
a.LastRefreshTime<='Filter.To' and a.ModelCode = 'mdlCode' and
exists(select top 1 * from FilterPN where Substring(epn, 1, 11) = a.H) and
exists(select top 1 * from FilterPN where Substring(eenter code herepn, 15, 2) = a.HV)
think to replace the enquoted variables with ur real values 'Filter.To'...
I'm beginner in linq to sql, I using the c# linq to sql and wrote this query:
var query_find = (from t in behzad.Interconnect_Traffic_Analysis_Details
where t.FILEID == FILE_ID && t.code_operator.Trim() == item.code_operator.Trim()
select new { t.moddat }).ToList();
I want to calculate sum of the t.moddat column, how can I convert this query to sum the values? Thanks.
t.moddat is a nvarchar(max) datatype and save into that double datatype value.
Try this
var query_find = (from t in behzad.Interconnect_Traffic_Analysis_Details
where t.FILEID == FILE_ID && t.code_operator.Trim() == item.code_operator.Trim()
select new
{
sum= t.moddat
}).ToList();
var sum= query_find.Sum(x => Convert.ToDouble(x.sum));
I am populating a class using Linq to SQL.
What I am trying to do is query my database, return two integer values and subtract the two values from each other, producing the result, but I can't think of a smart way to do it.
What can I do in this case ?
If it is not clear, , then this psuedocode implementation should clarify what functionality I wish for :
DECLARE #currentVal INT, #previousVal INT
#currentVal = SELECT VALUE
FROM Table1
WHERE Date = CURRDATE()
#previousVal = SELECT VALUE
FROM Table1
WHERE Date = MIN(Date)
RETURN #currentVal - #previousVal
But in Linq to SQL, (from o in context.Table1 where Date = currentDate select Value), how can I subtract the other value from this? Is this possible?
I'd stick to having it as a broken out set of queries, because you can then test if the values were actually returned or not and handle the case where too many values are returned:
var currentValResults = (from row in rows
where row.Date == DateTime.Now
select row.Value)
.ToArray();
var previousValResults = (from row in rows
let minDate = rows.Min(r => r.Date)
where row.Date == minDate
select row.Value)
.ToArray();
if (currentValResults.Length == 1 && previousValResults.Length == 1)
{
var diff = currentValResults[0] - previousValResults[0];
}
else
{
// Error condition?
}
Putting it all into a giant linq statement makes too many assumptions (or at least, my implementation does).
Why not simply do a cross join
var query=
from a in Table1 where a.Date == DateTime.Now
from b in Table1 where b.Date == Table1.Min(c=>c.Date)
select a.Amount - b.Amount;
var result=query.First();
Something like this would work to keep it into one trip to the db (Keep in mind this assumes that only two results will be returned):
int[] values = (from o in context.Table1
where Date = currentDate || Date = context.Table1.Min(x => x.Date)
order by Date descending
select value).ToArray();
return values[0] - values[1];
var currentVal = context.Table1.FirstOrDefault(t=>t.Date == DateTime.Now.Date);
var previousVal = context.Table1.FirstOrDefault(t=>t.Date == context.Table1.Min(d=>d.Date));
var result = currentVal - previousVal;
Or
from d in context.Table1
let prevVal = context.Table1.FirstOrDefault(t=>t.Date == context.Table1.Min(d=>d.Date));
where d.Date == DateTime.Now.Date
return new { d - prevVal };