if condition in IQueryable Join in LINQ query (Convert SQL to LINQ) - c#

As I need to convert following MS SQL Query in to Linq in C#
As I have tryed with IQueryable but not able to do .
As in that we need to check if condition is true then only need to go for join with table
Thanks in adv.
SELECT #sqlQuery = 'SELECT distinct tbl_1.col1 , tbl_1.col2, tbl_1.col3
FROM tbl_1 vd '
if(#Condetion is not null)
BEGIN
set #sqlQuery = #sqlQuery +'
Inner Join
( SELECT vml.*
FROM tbl_2 vml
INNER JOIN tbl_3 vm
ON tbl_1.IDCol = tbl_2.IDCol WHERE tbl_3.Name LIKE ''%'+#Condetion+'%'') A ON A.MessageID = vd.MessageID '
END
set #sqlQuery = #sqlQuery + 'INNER JOIN tbl_4 tbl
ON tbl.ColID12 = vd.ColID12
LEFT OUTER JOIN
vdd_typeid tblVdd ON tblVdd.TypeId=tbl_1.TypeId
INNER JOIN ...... '
EXEC sp_executesql #sqlQuery
As following i have try with LINQ
var query = from VD in _db.GetTable<tbl_1>() select VD ;
if (!string.IsNullOrEmpty(Category.Trim()))
{
query = query.Join((from VML in this._db.GetTable<tbl_1>()
join VM in this._db.GetTable<tbl_2>() on VML.MessageID equals VM.MessageID
where VM.Category.Name(Condetion),VD => new{VD.TypeId == [need write to write like this but can not VML.TypeId] }
}
query = query.Join(from TblVMS_def in this._db.GetTable<tbl_4>() on ........

It is extremely hard to deciper what you actually need, I've had a go here but it would possibly be far simpler with a copy of your Entity Diagram and a concise description of the data you are after.
I've had a go with what I think you want
var cat = string.IsNullOrWhiteSpace(Category) ? null : Category.Trim();
var query = from VD in _db.GetTable<tbl_1>()
join tbl in _db.GetTable<tbl_4>() on tbl.ColID12 equals VD.ColID12
join VM_I in _db.GetTable<tbl_2>() on VD.MessageID equals VM_I.MessageID
from VM in VM_I.DefaultIfEmpty()
where cat == null || VM.Category.Name.Contains(cat)
select new { col1 = VD.col1, col2 = VD.col2, VD.col3 };
you can then do query.Distinct() for distinct values;
Can I suggest that you use LinqPad to work out your query, it's far easier to work with and will also show you the resulting SQL

Related

Using Linq to Entities and havign a NOT IN clause

I have a SQL query that I am trying to convert to LINQ:
SELECT * FROM TABLE1
WHERE LICENSE_RTK NOT IN(
SELECT KEY_VALUE FROM TABLE2
WHERE REFERENCE_RTK = 'FOO')
So I wrote one query for inner query and then one query for the outer one and used Except:
var insideQuery = (from pkcr in this.Repository.Context.TABLE2 where pkcr.Reference_RTK == "FOO" select pkcr.Key_Value);
var outerQuery = (from pl in this.Repository.Context.TABLE1 select pl).Except(insideQuery);
But this is wrong. Cannot even compile it. What is the correct way of writing this?
You cannot compile second query, because Except should be used on Queryables of same type. But you are trying to apply it on Queryable<TABLE1> and Queryable<TypeOfTABLE2Key_Value>. Also I think you should use Contains here:
var keys = from pkcr in this.Repository.Context.TABLE2
where pkcr.Reference_RTK == "FOO"
select pkcr.Key_Value;
var query = from pl in this.Repository.Context.TABLE1
where !keys.Contains(pl.License_RTK)
select pl;
NOTE: Generated query will be NOT EXISTS instead of NOT IN, but that's what you want
SELECT * FROM FROM [dbo].[TABLE1] AS [Extent1]
WHERE NOT EXISTS
(SELECT 1 AS [C1]
FROM [dbo].[TABLE2] AS [Extent2]
WHERE ([Extent2].[Reference_RTK] == #p0) AND
([Extent2].[Key_Value] = [Extent1].[License_RTK]))

How can we create a dynamic sql query to run without considering if the parameters are passed or not in c# windows forms

I am using VS 2012 and SQL Express
I am trying to build a windows forms application to search through a database in C# and it has different controls on the form which are passed as parameters to the query.
The parameters in the query are not necessarily passed some times
I am trying with the following code sample.
SELECT a.ID AS 'DealID', a.TradeDate, c.COMPANYNAME AS 'Seller Company',
a.SellCommission, h.BROKER_FULLNAME AS 'Seller Trader',
j.DisplayName AS 'Seller Broker', d.COMPANYNAME AS 'Buyer Company',
a.BuyCommission, g.BROKER_FULLNAME AS 'Buyer Trader',
i.DisplayName AS 'Buyer Broker', e.PRODUCT_NAME, f.TYPE_DESC AS 'Quantity Type',
f.NBR_OF_GALLONS AS 'Quantity Multiplier', a.ContractVolume, a.TotalVolume,
a.DeliveryPoint, a.Price, a.ContractStart, a.ContractEnd
FROM Confirmations AS a WITH (nolock)
LEFT OUTER JOIN COMPANY AS c WITH (nolock)
ON c.COMPANY_ID = a.SellCompany
LEFT OUTER JOIN COMPANY AS d WITH (nolock)
ON d.COMPANY_ID = a.BuyCompany
LEFT OUTER JOIN BIOPRODUCTTYPES AS e WITH (nolock)
ON e.ID = a.ProductID
LEFT OUTER JOIN BIO_QUANTITY_TYPE AS f WITH (nolock)
ON f.ID = a.QuantityTypeID
LEFT OUTER JOIN COMPANYBROKER AS g WITH (nolock)
ON g.COMPANYBROKER_ID = a.BuyTrader
LEFT OUTER JOIN COMPANYBROKER AS h WITH (nolock)
ON h.COMPANYBROKER_ID = a.SellTrader
LEFT OUTER JOIN Users AS i WITH (nolock)
ON i.ID = a.BuyBroker
LEFT OUTER JOIN Users AS j WITH (nolock)
ON j.ID = a.SellBroker
WHERE (#fromdate IS NULL OR #fromdate=' ' OR a.TradeDate >= #fromdate)
AND (#todate IS NULL OR #todate=' ' OR a.TradeDate <= #todate)
AND (#buycompanyname IS NULL
OR #buycompanyname=""
OR a.BuyCompany = (SELECT COMPANY_ID
FROM COMPANY
WHERE (COMPANYNAME = #buycompanyname)))
AND (#sellcompanyname IS NULL
OR #sellcompanyname=""
OR a.SellCompany = (SELECT COMPANY_ID
FROM COMPANY
WHERE (COMPANYNAME =#sellcompanyname)))
AND (#product IS NULL OR #product="" OR e.PRODUCT_NAME= #product)";
Rather than using the above query, can I dynamically create a query, based on the parameters I passed which seems more logical as it doesn't look for the records if the column in the table has a null value.
This is what ORM's where created for. By replacing your hard coded querys with somthing that builds your query at runtime (like Entity Framework or NHibernate) and it builds the both the SELECT and the WHERE portions of the query for you.
With proper set up objects you could use Entity Framework like the following
Nullable<DateTime> fromDate = //...
Nullable<DateTime> toDate = //...
string buyCompany = //...
//(Snip)
using(var ctx = new MyContext())
{
var query = ctx.Order;
if(fromDate.HasValue)
query = query.Where(ent=> ent.TradeDate >= fromDate.Value);
if(toDate.HasValue)
query = query.Where(ent => ent.TradeDate <= toDate.Value);
if(String.IsNullOrWhitespace(buyCompany) == false)
query = query.Where(ent => ent.BuyCompany.CompanyName = buyCompany);
//(Snip)
return query.ToList();
}
If you are calling a stored procedure, I'd suggest dynamically building the SQL string to only use the parameters you'll be using, then calling sp_executesql. The stored procedure would look like this:
DECLARE #sql =nvarchar(MAX), #Parameters nvarchar(max)
SET #sql = 'SELECT * FROM [dbo].[Foo] WHERE Column1 = #Param1'
SET #Parameters = '#Param1 nvarchar(32), #Param2 nvarchar(32)'
IF(#Param2 is not null and #Param2 <> ' ') SET #sql = #sql + ' AND Column2 = #Param2'
EXEC sp_executesql #Sql, #Parameters, #Param1, #Param2
The idea is basically the same if you're building the query string in C# instead of a stored procedure:
command.CommandText = "SELECT * FROM [dbo].[Foo] WHERE Column1 = #Param1";
command.Parameters.AddWithValue("#Param1", param1);
if(!String.IsNullOrEmpty(param2))
{
command.CommandText += " AND Column2 = #Param2";
command.Parameters.AddWithValue("#Param2", param2);
}
Yes, just build your sql query string out.
Set your SqlCommand.CommandType to CommandType.Text
then set your parameters with SqlCommand.Parameters.AddWidthValue(string, object);

Linq Join with a Group By

Ok, I am trying to replicate the following SQL query into a Linq expression:
SELECT
I.EmployeeNumber,
E.TITLE,
E.FNAM,
E.LNAM
FROM
Incidents I INNER JOIN Employees E ON I.IncidentEmployee = E.EmployeeNumber
GROUP BY
I.EmployeeNumber,
E.TITLE,
E.FNAM,
E.LNAM
Simple enough (or at least I thought):
var query = (from e in contextDB.Employees
join i in contextDB.Incidents on i.IncidentEmployee = e.EmployeeNumber
group e by new { i.IncidentEmployee, e.TITLE, e.FNAM, e.LNAM } into allIncEmps
select new
{
IncEmpNum = allIncEmps.Key.IncidentEmployee
TITLE = allIncEmps.Key.TITLE,
USERFNAM = allIncEmps.Key.FNAM,
USERLNAM = allIncEmps.Key.LNAM
});
But I am not getting back the results I exprected, so I fire up SQL Profiler to see what is being sent down the pipe to SQL Server and this is what I see:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
COUNT(1) AS [A1]
FROM ( SELECT DISTINCT
[Extent2].[IncidentEmployee] AS [IncidentEmployee],
[Extent1].[TITLE] AS [TITLE],
[Extent1].[FNAM] AS [FNAM],
[Extent1].[LNAM] AS [LNAM]
FROM [dbo].[Employees] AS [Extent1]
INNER JOIN [dbo].[INCIDENTS] AS [Extent2] ON ([Extent1].[EmployeeNumber] = [Extent2].[IncidentEmployee]) OR (([Extent1].[EmployeeNumber] IS NULL) AND ([Extent2].[IncidentEmployee] IS NULL))
) AS [Distinct1]
) AS [GroupBy1]
As you can see from the SQL string that was sent toSQL Server none of the fields that I was expecting to be return are being included in the Select clause. What am I doing wrong?
UPDATE
It has been a very long day, I re-ran the code again and now this is the SQL that is being sent down the pipe:
SELECT
[Distinct1].[IncidentEmployee] AS [IncidentEmployee],
[Distinct1].[TITLE] AS [TITLE],
[Distinct1].[FNAM] AS [FNAM],
[Distinct1].[LNAM] AS [LNAM]
FROM ( SELECT DISTINCT
[Extent1].[OFFNUM] AS [OFFNUM],
[Extent1].[TITLE] AS [TITLE],
[Extent1].[FNAM] AS [FNAM],
[Extent1].[LNAM] AS [LNAM]
FROM [dbo].[Employees] AS [Extent1]
INNER JOIN [dbo].[INCIDENTS] AS [Extent2] ON ([Extent1].[EmployeeNumber] = [Extent2].[IncidentEmployee]) OR (([Extent1].[EmployeeNumber] IS NULL) AND ([Extent2].[IncidentEmployee] IS NULL))
) AS [Distinct1]
But I am still not seeing results when I try to loop through the record set
foreach (var emps in query)
{
}
Not sure why the query does not return what it should return, but it occurred to me that since you only query the group key and not any grouped results you've got nothing but a Distinct():
var query =
(from e in contextDB.Employees
join i in contextDB.Incidents on i.IncidentEmployee equals e.EmployeeNumber
select new
{
IncEmpNum = i.IncidentEmployee
TITLE = e.TITLE,
USERFNAM = e.FNAM,
USERLNAM = e.LNAM
}).Distinct();
But EF was smart enough to see this as well and created a DISTINCT query too.
You don't specify which result you expected and in what way the actual result was different, but I really can't see how the grouping can produce a different result than a Distinct.
But how did your code compile? As xeondev noticed: there should be an equals in stead of an = in a join statement. My compiler (:D) does not swallow it otherwise. The generated SQL join is strange too: it also matches records where both joined values are NULL. This makes me suspect that at least one of your keys (i.IncidentEmployee or e.EmployeeNumber) is nullable and you should either use i.IncidentEmployee.Value or e.EmployeeNumber.Value or both.

How to use the results of the previous query in the next query?

As a result of this query I have a table:
select i.id, o.[name] from Item i
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
Now I need to use the result of this table in the next query:
select PriceListItem.ProductExternalId, #id.Id, #id.FriendlyName, #id.BriefWiki,
[PriceListItem].[ProductExternalDesc]
from [#id]
inner join [Product] on Product.ItemId = #name and Product.InstanceId = #id.ID
inner join [PriceListItem] on Product.ID = PriceListItem.ProductId
instead of '#id' I should use data from the table with name= id, and instead of '#name' I should use data from the table with name= name
Standard SQL way, works in most RDBMS
select PriceListItem.ProductExternalId, #id.Id, #id.FriendlyName, #id.BriefWiki,
[PriceListItem].[ProductExternalDesc]
from
(
select i.id, o.[name] from Item i
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
)
X
inner JOIN
[#id] ON X.id = #id.id --change here as needed
inner join [Product] on Product.ItemId = #name and Product.InstanceId = #id.ID
inner join [PriceListItem] on Product.ID = PriceListItem.ProductId*
Since you're on SQL 2K8 you can use a CTE:
-- You may need a ; before WITH as in ;WITH
WITH FirstQuery AS (
select i.id, o.[name] from Item i
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
)
select PriceListItem.ProductExternalId,
FQ.Id,
-- Neither of these are in your FirstQuery so you can not use them
-- #id.FriendlyName, #id.BriefWiki,
[PriceListItem].[ProductExternalDesc]
from FirstQuery FQ
inner join [Product] on Product.ItemId = FQ.name
and Product.InstanceId = FQ.ID
inner join [PriceListItem] on Product.ID = PriceListItem.ProductId;
From the queries alone it's tough to tell how you plan to JOIN them, but this will allow you to make use of the first query in the subsequent one.
Looks like you have some syntax errors in your second query - #id.id?
select i.id, o.[name] from Item i
into #temp_table
LEFT OUTER JOIN sys.objects o on o.[name]='I' + cast(i.id as nvarchar(20))
where o.name is not null
Now you can use #temp_table as you want :)

search query in entity framework 3.5

I need to build a search query on Customers table join with orders table
string firstname = "Joe";
string emailFilter = "joe#email.com";
string city=null;
In SQL we can make like this
SELECT #sql =
'SELECT * from
FROM dbo.Orders o
inner join
JOIN dbo.Customers c ON o.CustomerID = c.CustomerID
WHERE 1 = 1'
IF #firstname IS NOT NULL
SELECT #sql = #sql + ' AND c.firstname= #firstname'
IF #city IS NOT NULL
SELECT #sql = #sql + ' AND c.city >= #city'
I need to build a entity framework 3.5 linq query joined with orders and customers table
with dynamic search condition.
if the values are not null, i need to use in where clause in linq
I am new to Linq.
shall we need to use Iqueryable.
Any help appreciated.
Thanks
You can try something like :
var result = from o in context.Orders.include("customers")
where o.city == (city == null ? o.city : city) && o.firstname == (firstname == null ? o.firstname : firstname)
select o;
You can check Dynamic Linq here http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx it will help you or search stackoverflow.com for dynamic-linq tag questions and answers https://stackoverflow.com/questions/tagged/dynamic-linq

Categories

Resources