search query in entity framework 3.5 - c#

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

Related

Linq equivalent of aggregate function on multiple tables in one database trip

I have a table function which returns table names and number of entries within that table :
CREATE FUNCTION [dbo].[ufnGetLookups] ()
RETURNS
#lookupsWithItemCounts TABLE
(
[Name] VARCHAR(100),
[EntryCount] INT
)
AS
BEGIN
INSERT INTO #lookupsWithItemCounts([Name],[EntryCount])
VALUES
('Table1', (SELECT COUNT(*) FROM Table1)),
('Table2', (SELECT COUNT(*) FROM Table2)),
('Table3', (SELECT COUNT(*) FROM Table))
RETURN;
END
What would be the Linq equivalent of above simple function? Notice that I want to get the result in one single shot and the speed of the operation is quite important for me. If I realise that the converted linq to sql results in a massive bulky sql with performance hit, I would rather stick to my existing user defined function and forget about the linq equivilant.
You can do that with a UNION query. EG
var q = db.Books.GroupBy(g => "Books").Select(g => new { Name = g.Key, EntryCount = g.Count() })
.Union(db.Authors.GroupBy(g => "Authors").Select(g => new { Name = g.Key, EntryCount = g.Count() }));
var r = q.ToList();
Not an EF guy, and not sure if this would be more performant.
Select TableName = o.name
,RowCnt = sum(p.Rows)
From sys.objects as o
Join sys.partitions as p on o.object_id = p.object_id
Where o.type = 'U'
and o.is_ms_shipped = 0x0
and index_id < 2 -- 0:Heap, 1:Clustered
--and o.name in ('Table1','Table2','Table3' ) -- Include (or not) your own filter
Group By o.schema_id,o.name
Note: Wish I could recall the source of this, but I've used it in my discovery process.

LINQ - select statement in the selected column

i am intend to convert the following query into linQ
SELECT TOP 100 S.TxID,
ToEmail,
[Subject],
ProcessedDate,
[Status] = (CASE WHEN EXISTS (SELECT TxID FROM TxBounceTracking
WHERE TxID = S.TxID)
THEN 'Bounced'
WHEN EXISTS (SELECT TxID FROM TxOpenTracking
WHERE TxID = S.TxID)
THEN 'Opened'
ELSE 'Sent' END)
FROM TxSubmissions S
WHERE S.UserID = #UserID
AND ProcessedDate BETWEEN #StartDate AND #EndDate
ORDER BY ProcessedDate DESC
The following code is the linq that i converted.
v = (from a in dc.TxSubmissions
where a.ProcessedDate >= datefrom && a.ProcessedDate <= dateto && a.UserID == userId
let bounce = (from up in dc.TxBounceTrackings where up.TxID == a.TxID select up)
let track = (from up in dc.TxOpenTrackings where up.TxID == a.TxID select up)
select new { a.TxID, a.ToEmail, a.Subject,
Status = bounce.Count() > 0 ? "Bounced" : track.Count() > 0 ? "Opened" : "Sent",
a.ProcessedDate });
However this linq is too slow because the bounce and track table, how should i change the linq query to select one row only to match the SQL query above >>
SELECT TxID FROM TxOpenTracking WHERE TxID = S.TxID
in my selected column, so it can execute faster.
Note that the record contained one million records, thats why it lag
As you don't care about readability because you will end up generating the query via EF you can try to join with those two tables. (it looks that TxID is a FK or a PK/FK)
More about JOIN vs SUB-QUERY here: Join vs. sub-query
Basically your SQL looks like this:
SELECT TOP 100 S.TxID, ToEmail, [Subject], ProcessedDate,
[Status] = (CASE WHEN BT.TxID IS NOT NULL
THEN 'Bounced'
WHEN OP.TxID IS NOT NULL
THEN 'Opened'
ELSE 'Sent' END)
FROM TxSubmissions S
LEFT JOIN TxBounceTracking BT ON S.TxID = BT.TxID
LEFT JOIN TxOpenTracking OP ON S.TxID = OP.TxID
WHERE S.UserID = #UserID
AND ProcessedDate BETWEEN #StartDate AND #EndDate
ORDER BY ProcessedDate DESC
And then, you can try to convert it to LINQ something like:
v = (from subs in dc.TxSubmissions.Where(sub => sub.ProcessedDate >= datefrom && sub.ProcessedDate <= dateto && sub.UserID == userId)
from bts in dc.TxBounceTrackings.Where(bt => bt.TxID == subs.TxID).DefaultIfEmpty()
from ots in dc.TxOpenTrackings.Where(ot => ot.TxID == subs.TxID).DefaultIfEmpty()
select new { });
More about left join in linq here: LEFT JOIN in LINQ to entities?
Also if you remove default if empty you'll get a inner join.
Also you need to take a look at generated SQL in both cases.

Converting SQL Statement with Multiple Left Outer Joins and Various Clauses to LINQ

I've been trying to create associations and navigation properties to simplify my LINQ query a little; however, because of the complicated, proprietary database I'm working with it's been really difficult.
For most of this process, I've been using the database first approach on EF5. I couldn't create associations and navigation properties using database first, so I tried to create foreign keys on SQL Server, but was unsuccessful in that.
For my next step, I tried to create the tables, associations, and navigation properties using the code first approach; however, again, because of the necessities of the database and server I'm working with, I was unsuccessful in simplifying my query.
My last resort is just to do what I was originally trying to do in this question. That is to get this LINQ query:
from item in db2.OrderFormDump
join icp in db2.IcPricP on item.NODASHITEMNO equals icp.ITEMNO into icpGroup
from iG in icpGroup.DefaultIfEmpty()
join itemInfo in db2.WebItemInfo on item.ITEMNO equals itemInfo.ITEMNO into itemInfoGroup
from iIG in itemInfoGroup.DefaultIfEmpty()
join weboeordh in db2.WebOEOrdH on "brian" equals weboeordh.USER into weboeordhGroup
from wOEODHG in weboeordhGroup.DefaultIfEmpty()
join weboeordd in db2.WebOEOrdD on new { itemno = item.NODASHITEMNO, orduniq = wOEODHG.ORDUNIQ } equals new { itemno = weboeordd.ITEMNO, orduniq = weboeordd.ORDUNIQ } into weboeorddGroup
from wOEODG in weboeorddGroup.DefaultIfEmpty()
join weboeordsubmit in db2.WebOEOrdSubmit on wOEODG.ORDUNIQ equals weboeordsubmit.ORDUNIQ into weboeordsubmitGroup
from wOEOSG in weboeordsubmitGroup.DefaultIfEmpty()
join webloginaccess in db2.WebLoginAccess on "brian" equals webloginaccess.USER into webloginaccessGroup
from wLAG in webloginaccessGroup.DefaultIfEmpty()
join arcus in db2.Arcus on wLAG.CUSTID equals arcus.IDCUST into arcusGroup
from aG in arcusGroup
where (item.ALLOWINBC == "Yes" && item.ALLOWINAB == "Yes")
&& (item.BASEDESCRIPTION.Contains("dude") || item.DESCRIPTION.Contains("dude") || item.CATEGORY.Contains("dude") || item.FOODACCSPEC.Contains("dude") || item.ITEMBRAND.Contains("dude") || item.ITEMGROUP.Contains("dude") || item.ITEMNO.Contains("dude") || item.ITEMSUBTYPE.Contains("dude") || item.ITEMTYPE.Contains("dude") || iIG.INFO.Contains("dude") || item.UPC.Contains("dude") || item.UPC.Substring(2, 10).Contains("dude"))
&& (iG.CURRENCY == "CDN" && iG.DPRICETYPE == 1)
&& wOEODG.ORDUNIQ != wOEODHG.ORDUNIQ
&& iG.PRICELIST == aG.PRICLIST
orderby item.BASEDESCRIPTION
select new { item.ITEMNO, item.BASEDESCRIPTION, iIG.INFO, item.UPC, iG.UNITPRICE, item.CASEQTY, wOEODG.QTY } into x
group x by new { x.ITEMNO, x.BASEDESCRIPTION, x.INFO, x.UPC, x.UNITPRICE, x.CASEQTY, x.QTY } into items
select items;
To get the same results as this SQL query:
DECLARE #search varchar(50) = 'dude'
SELECT orderformdump.itemno,basedescription,info,upc,CAST(UNITPRICE AS DECIMAL(18,2)),caseqty, sum(qty) AS userquantity
FROM PPPLTD.[dbo].[ORDERFORMDUMP]
LEFT JOIN PPPLTD.dbo.ICPRICP ON replace(PPPLTD.[dbo].[ORDERFORMDUMP].[ITEMNO],'-','') = ICPRICP.ITEMNO
LEFT JOIN PPPLTD.dbo.WEBITEMINFO ON ORDERFORMDUMP.ITEMNO = WEBITEMINFO.ITEMNO
LEFT JOIN pppltd.dbo.weboeordh ON [user] = 'brian'
LEFT JOIN pppltd.dbo.weboeordd ON pppltd.dbo.WEBOEORDD.ITEMNO = REPLACE(pppltd.dbo.ORDERFORMDUMP.ITEMNO,'-','') and weboeordd.ORDUNIQ = weboeordh.orduniq
Left JOIN pppltd.dbo.weboeordsubmit ON weboeordsubmit.orduniq = weboeordd.ORDUNIQ and weboeordd.ORDUNIQ != weboeordsubmit.orduniq
LEFT JOIN PPPLTD.dbo.WEBLOGINACCESS ON WEBLOGINACCESS.[USER] = 'brian'
LEFT JOIN PPPLTD.dbo.ARCUS ON ARCUS.IDCUST = WEBLOGINACCESS.CUSTID
where (allowinbc = 'Yes' or allowinab = 'Yes')
AND [PRICELIST] = ARCUS.PRICLIST
and [CURRENCY] = 'CDN' and DPRICETYPE = 1
and (itemgroup like '%' + #search + '%' or itemtype like '%' + #search + '%' or itembrand like '%' + #search + '%'
or subcat like '%' + #search + '%' or orderformdump.description like '%' + #search + '%' or basedescription like '%'+ #search + '%'
or orderformdump.ITEMNO like '%'+#search+'%' or UPC like '%'+#search+'%' or (select top 1 1 from pppltd.dbo.ICITEMO where OPTFIELD like 'UPC%' and VALUE like '%'+#search+'%'
and ITEMNO = pppltd.dbo.ORDERFORMDUMP.itemno) is not null)
group by ORDERFORMDUMP.ITEMNO,BASEDESCRIPTION,info,UPC,CAST(UNITPRICE AS DECIMAL(18,2)),caseqty
order by basedescription
When I execute the LINQ on LINQPad, it produces this SQL:
DECLARE #p0 NVarChar(1000) = '-'
DECLARE #p1 NVarChar(1000) = ''
DECLARE #p2 VarChar(1000) = 'brian'
DECLARE #p3 NVarChar(1000) = '-'
DECLARE #p4 NVarChar(1000) = ''
DECLARE #p5 VarChar(1000) = 'brian'
DECLARE #p6 VarChar(1000) = 'Yes'
DECLARE #p7 VarChar(1000) = 'Yes'
DECLARE #p8 VarChar(1000) = '%dude%'
DECLARE #p9 VarChar(1000) = '%dude%'
DECLARE #p10 VarChar(1000) = '%dude%'
DECLARE #p11 VarChar(1000) = '%dude%'
DECLARE #p12 VarChar(1000) = '%dude%'
DECLARE #p13 VarChar(1000) = '%dude%'
DECLARE #p14 VarChar(1000) = '%dude%'
DECLARE #p15 VarChar(1000) = '%dude%'
DECLARE #p16 VarChar(1000) = '%dude%'
DECLARE #p17 VarChar(1000) = '%dude%'
DECLARE #p18 VarChar(1000) = '%dude%'
DECLARE #p19 Int = 2
DECLARE #p20 Int = 10
DECLARE #p21 VarChar(1000) = '%dude%'
DECLARE #p22 VarChar(1000) = 'CDN'
DECLARE #p23 Int = 1
-- EndRegion
SELECT [t10].[ITEMNO], [t10].[BASEDESCRIPTION], [t10].[value] AS [INFO], [t10].[UPC], [t10].[value2] AS [UNITPRICE], [t10].[CASEQTY], [t10].[value3] AS [QTY]
FROM (
SELECT [t9].[ITEMNO], [t9].[BASEDESCRIPTION], [t9].[value], [t9].[UPC], [t9].[value2], [t9].[CASEQTY], [t9].[value3]
FROM (
SELECT [t0].[ITEMNO], [t0].[BASEDESCRIPTION], [t2].[INFO] AS [value], [t0].[UPC], [t1].[UNITPRICE] AS [value2], [t0].[CASEQTY], [t5].[QTY] AS [value3], [t0].[ALLOWINBC], [t0].[ALLOWINAB], [t0].[DESCRIPTION], [t0].[CATEGORY], [t0].[FOODACCSPEC], [t0].[ITEMBRAND], [t0].[ITEMGROUP], [t0].[ITEMSUBTYPE], [t0].[ITEMTYPE], [t1].[CURRENCY], [t1].[DPRICETYPE], [t5].[ORDUNIQ], [t4].[ORDUNIQ] AS [ORDUNIQ2], [t1].[PRICELIST], [t8].[PRICLIST]
FROM [ORDERFORMDUMP] AS [t0]
LEFT OUTER JOIN [ICPRICP] AS [t1] ON REPLACE([t0].[ITEMNO], #p0, #p1) = [t1].[ITEMNO]
LEFT OUTER JOIN [WEBITEMINFO] AS [t2] ON [t0].[ITEMNO] = [t2].[ITEMNO]
LEFT OUTER JOIN (
SELECT [t3].[ORDUNIQ]
FROM [WEBOEORDH] AS [t3]
WHERE #p2 = [t3].[USER]
) AS [t4] ON 1=1
LEFT OUTER JOIN [WEBOEORDD] AS [t5] ON (REPLACE([t0].[ITEMNO], #p3, #p4) = [t5].[ITEMNO]) AND ([t4].[ORDUNIQ] = [t5].[ORDUNIQ])
LEFT OUTER JOIN (
SELECT [t6].[CUSTID]
FROM [WEBLOGINACCESS] AS [t6]
WHERE #p5 = [t6].[USER]
) AS [t7] ON 1=1
LEFT OUTER JOIN [ARCUS] AS [t8] ON [t7].[CUSTID] = [t8].[IDCUST]
) AS [t9]
WHERE ([t9].[ALLOWINBC] = #p6) AND ([t9].[ALLOWINAB] = #p7) AND (([t9].[BASEDESCRIPTION] LIKE #p8) OR ([t9].[DESCRIPTION] LIKE #p9) OR ([t9].[CATEGORY] LIKE #p10) OR ([t9].[FOODACCSPEC] LIKE #p11) OR ([t9].[ITEMBRAND] LIKE #p12) OR ([t9].[ITEMGROUP] LIKE #p13) OR ([t9].[ITEMNO] LIKE #p14) OR ([t9].[ITEMSUBTYPE] LIKE #p15) OR ([t9].[ITEMTYPE] LIKE #p16) OR ([t9].[value] LIKE #p17) OR ([t9].[UPC] LIKE #p18) OR (SUBSTRING([t9].[UPC], #p19 + 1, #p20) LIKE #p21)) AND ([t9].[CURRENCY] = #p22) AND ([t9].[DPRICETYPE] = #p23) AND ([t9].[ORDUNIQ] <> [t9].[ORDUNIQ2]) AND ([t9].[PRICELIST] = [t9].[PRICLIST])
GROUP BY [t9].[ITEMNO], [t9].[BASEDESCRIPTION], [t9].[value], [t9].[UPC], [t9].[value2], [t9].[CASEQTY], [t9].[value3]
) AS [t10]
ORDER BY [t10].[BASEDESCRIPTION]
UPDATE
As per HBomb's answer, I decided to create a stored procedure with parameters instead of doing multiple joins:
CREATE PROCEDURE PRODUCT_PROCEDURE
#USERID VARCHAR(MAX)
AS
BEGIN
SELECT distinct datawarehouse.dbo.orderformdump.itemno, basedescription,info,upc,CAST((SELECT [UNITPRICE] FROM PPPLTD.dbo.[ICPRICP] WHERE [ITEMNO] = replace([DataWarehouse].[dbo].[ORDERFORMDUMP].[ITEMNO],'-','') AND [PRICELIST] = (select top 1 priclist from PPPLTD.dbo.ARCUS where IDCUST = (select top 1 CUSTID from PPPLTD.dbo.WEBLOGINACCESS where [USER] = #USERID)) and [CURRENCY] = 'CDN' and DPRICETYPE = 1) AS DECIMAL(18,2))as price,caseqty, qty AS userquantity FROM [DataWarehouse].[dbo].[ORDERFORMDUMP] LEFT JOIN pppltd.dbo.weboeordd ON pppltd.dbo.WEBOEORDD.ITEMNO = REPLACE(datawarehouse.dbo.ORDERFORMDUMP.ITEMNO,'-','') and orduniq not in (select orduniq from pppltd.dbo.weboeordsubmit) and WEBOEORDD.ORDUNIQ in (select orduniq from pppltd.dbo.weboeordh where [user] = #USERID) LEFT JOIN DATAWAREHOUSE.dbo.webiteminfo on webiteminfo.itemno = orderformdump.itemno where (allowinbc = 'Yes' or allowinab = 'Yes') order by BASEDESCRIPTION
END
Then I used Entity Framework's Database First approach to add my stored procedure and it has created a new DbContext with a method that sets the 'USERID' parameter in my stored procedure:
public partial class DataWarehouseEntities : DbContext
{
public DataWarehouseEntities()
: base("name=DataWarehouseEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual ObjectResult<PRODUCT_PROCEDURE_Result> PRODUCT_PROCEDURE(string USERID)
{
var USERIDParameter = USERID != null ?
new ObjectParameter("USERID", USERID) :
new ObjectParameter("USERID", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<PRODUCT_PROCEDURE_Result>("PRODUCT_PROCEDURE", USERIDParameter);
}
}
I've also tried:
var USERIDParameter = USERID != null ? new SqlParameter("USERID", USERID) : new SqlParameter("USERID", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteStoreQuery<PRODUCT_PROCEDURE‌​_Result>("PRODUCT_PROCEDURE #USERID", USERIDParameter);
and finally, I tried running a much more simplified LINQ query on the results of my stored procedure:
var products = db2.PRODUCT_PROCEDURE(username).Where
(item => item.basedescription.Contains(searchword)
|| item.info.Contains(searchword)
|| item.itemno.Contains(searchword)
|| item.itemno.Contains(searchword.Replace("-", ""))
|| item.upc.Contains(searchword));
However, now I'm getting a NullReferenceException because the query isn't returning any results.
UPDATE #2
Executing the stored procedure is not causing the NullReferenceException. the problem is the LINQ query.
I found out that when I have var products = db2.PRODUCT_PROCEDURE(username).ToList() alone, it returns results, but as soon as I try to add a where clause on it, it returns null.
SOLUTION
With HBomb's help, I solved this issue. First of all, instead creating multiple joins in LINQ, or create associations, and navigation properties, it's much easier to create a view or a stored procedure in your database then write a simple LINQ query using the results of that (example of how to do that is above).
I found out that I was getting my NullReferenceException because some values in the database for my info property were null. All I had to do to fix that issue was modify the stored procedure to change to info column to isnull(info,'') as info.
Lastly, just for better search results, I changed my query:
var searchWords = searchword.ToLower().Split(' ');
var products = db2.PRODUCT_PROCEDURE(username).ToList()
.Where
(item => item.basedescription.ToLower().Contains(searchWords[0])
|| item.info.ToLower().Contains(searchWords[0])
|| item.itemno.Contains(searchword)
|| item.itemno.Contains(searchword.Replace("-", ""))
|| item.upc.Contains(searchword)
|| (item.price.ToString() == searchword
&& item.price.ToString() != null));
if (searchWords.Length > 1)
{
for (int x = 0; x < searchWords.Length-1; x++)
{
products = products.Where(i => i.basedescription.ToLower().Contains(searchWords[x]) || i.info.ToLower().Contains(searchWords[x]));
}
}
Thank you.
If you wrap the Sql in a stored Procedure, you could just use EF to call the procedure. Here's one way:
var searchParameter = new SqlParameter("#search", mySearchValue);
this.Database.SqlQuery<YourEntityTypeForReturnVal>("MyProcedureName, #search", searchParameter);
You can that create a parameterized stored procedure as a wrapper for your Sql:
CREATE PROCEDURE MyProcedureName
#search varchar(50)
AS
BEGIN
-- Copy and paste your existing Sql Query here, minus the variable declaration
END
Sometimes the best (and hardest) thing we can do as developers is to take a step back and ask "should I be doing it this way" instead of asking "how do I do it this way."
I'm arriving after the battle, but could this be a job for QueryFirst? You can paste your SQL into a query template as is, but it stays in your application (easier source-control, versioning, maintenance). And the generated classes make it directly usable from your application code.

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);

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

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

Categories

Resources