Ternary Operator in LINQ Query - c#

I have a LINQ query that I need to use a ternary operator on so certain joins are used based on certain criteria. So this is my query.
var lData = (from r in gServiceContext.CreateQuery("campaignresponse")
join a in gServiceContext.CreateQuery("activityparty") on ((EntityReference)r["activityid"]).Id equals ((EntityReference)a["activityid"]).Id
//tenary statement here
join c in gServiceContext.CreateQuery("contact") on ((EntityReference)a["partyid"]).Id equals c["contactid"]
where ((EntityReference)r["new_distributorid"]).Id.Equals(lProfileProperty.PropertyValue)
select new
{
});
This is what I want to do.
If r["new_distributorid"] == 1 I need to use:
join c in gServiceContext.CreateQuery("contact") on ((EntityReference)a["partyid"]).Id equals c["contactid"]
if r["new_distributorid"] == 2 then I need to use:
join c in gServiceContext.CreateQuery("account") on ((EntityReference)a["partyid"]).Id equals c["accountid"]
and if r["new_distributorid"] == 3 then I need to use:
join c in gServiceContext.CreateQuery("lead") on ((EntityReference)a["partyid"]).Id equals c["leadid"]
So basically is new_distributor == 1 I need to use a certain join if its a 2 I need another join and if its a 3 I need another join.
Is this possible? If it is, how would I go about setting that up?
Thanks!

All that's changing is a single string value, so just determine that string value before you start defining the query:
string tableName = "";
switch(r["new_distributorid"])
{
case(1):
tableName = "contact";
case(2):
tableName = "account";
case(3):
tableName = "lead";
}
string tableID = tableName + "id";
//...
join c in gServiceContext.CreateQuery(tableName)
on ((EntityReference)a["partyid"]).Id equals c[tableID]

Related

What's wrong with the joins in this LINQ query?

I'm trying to replicate the following SQL query in LINQ:
SELECT *
FROM Table1 AS D INNER JOIN Table2 AS DV ON D.Table1Id = DV.Table1Id
INNER JOIN Table3 AS VT ON DV.Table3Id = VT.Table3Id
INNER JOIN Table4 AS C ON DV.CurrencyId = C.CurrencyId
INNER JOIN Table5 AS FP ON DV.DVDate BETWEEN FP.StartDate AND FP.EndDate
INNER JOIN Table6 AS FX ON DV.CurrencyId = FX.FromCurrencyId AND FX.ToCurrencyId = 'USD' AND FX.FiscalPeriodId = FP.FiscalPeriodId
This is what I have in LINQ:
from d in db.Table1
join dv in db.Table2 on d.Table1Id equals dv.Table1Id
join vt in db.Table3 on dv.Table3Id equals vt.Table3Id
join c in db.Table4 on dv.CurrencyId equals c.CurrencyId
join fp in db.Table5 on dv.DVDate >= fp.StartDate && dv.DVDate <= fp.EndDate //error on this line
join fx in db.Table6 on dv.CurrencyId equals fx.FromCurrencyId && fx.ToCurrencyId equals "USD" && fx.FiscalPeriodId equals fp.FiscalPeriodId //error also on this line
The last two joins to fp and fx are the problem but it's not clear to me what's wrong, it doesn't seem to like && but there's no and keyword like there is an equals that replaces =.
I've removed the select portion from LINQ as it's not relevant to the problem and I'd like to avoid spending more time obfuscating table and field names.
"A join clause performs an equijoin. In other words, you can only base matches on the equality of two keys. Other types of comparisons such as "greater than" or "not equals" are not supported. To make clear that all joins are equijoins, the join clause uses the equals keyword instead of the == operator. "
reference: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/join-clause
you need to do this in the where clause. Like here:
https://stackoverflow.com/a/3547706/3058487
To do a join using composite keys, you need to do something like here:
new { dv.CurrencyId, fp.FiscalPeriodId } equals new { CurrencyId = fx.ToCurrencyId, fx.FiscalPeriodId }
Reference:
https://learn.microsoft.com/en-us/dotnet/csharp/linq/join-by-using-composite-keys

How to translate this inner join T-SQL into LINQ-to-Entities?

I have a snippet of Stored Procedure:
...
SELECT B.BinID, AverageCost, SUM(Qty) AS Qty
FROM #CurrentReturn R INNER JOIN Bins B ON R.BinCode = B.BinCode AND B.StoreroomID = #StoreroomID
...
#StorerroomID is one of the SP parameters.
Now I am trying to translate it into LINQ to Entities,
var AverageCostList = from r in CurrentReturn
join b in BinQuery on new {r.BinCode, b.StoreroomID} equals new {b.BinCode, storeroomID}
It does not work, as the type on the L.H.S. of equals cannot contains fields in b.
So is there any way to translate such an inner join SQL into LINQ?
i would put the B.StoreroomID = #StoreroomID comparison into ther where clause
from r in CurrentReturn
join b in BinQuery
on r.BinCode equals b.BinCode
where b.StoreroomID == storeroomID

LINQ join with multiple conditions of different kind

I'm trying to translate following T-SQL query into LINQ:
SELECT * FROM table_A JOIN table_B ON table_A.key = table_B.key AND
table_A.Trouble <> table_B.Trouble
Stackoverflow is full with similar questions, but in my case there are two conditions but each of them has different operator ("equals to" and "not equals to"). Is there any way to get the same result using LINQ?
You can't use the join syntax, you have to use a where clause to connect the two
var query = from a in table_A
from b in table_B
where a.key = b.key &&
a.Trouble != b.Trouble
select new { a, b };
You can also write this query. It should be work fast
var query = from a in table_A
from b in table_B.where(x=>x.key==a.key && x.Trouble != a.Trouble)
select new { a, b };

Left Join If A Certain Field Is A Certain Value?

I'm having a difficult time building a left join query that does something like this:
var Results =
from a in Db.Table1
join b in Db.Table2 on a.Id equals b.Id into c //IF b.Value2 == 1
from d in c.DefaultIfEmpty()
select new {Table1 = a};
The problem I'm having is that I simply can't add "where b.Value2==1" before the "select" because this will exclude all joined rows with b.Value2 != 1.
What I want to have happen is for the columns to join only if b.Value2==1, and if not, it will keep the row (instead of excluding them as the where described above would), but just not join the two columns.
I hope this makes sense and there is a way to do this, thanks!
Edit:
Table1
ValueA=1,ValueB=1
ValueA=2,ValueB=2
Table2
ValueB=1,ValueC=1
ValueB=2,ValueC=2
Desired Result (joining on Table1.ValueB==Table2.ValueB Where Table2.ValueC == 2, still include this row, but just don't join it to Table2):
ValueA=1, ValueB=1, ValueC=null //ValueC=null because where Table2.ValueB==1,ValueC != 2
ValueA=2, ValueB=2, ValueC=2
This should work, basically create a dummy var and join on it. The problem is this doesn't make for a friendly push down operation to the DB.
var Results =
from a in Db.Table1
join b in Db.Table2 on
new { ID= a.Id, Bit = true }
equals
new { ID = b.Id, Bit = b.Value ==1 }
into c
from d in c.DefaultIfEmpty()
select new {
Table1 = a,
Table2= d //will be null if b.Value is not 1
};
add the where, then add another query that's just for b.Value2 != 1, merge both queries?
Create two linq queries, which will be composed into one sql query:
The first query will do a regular outer join
var partResult= from a in Db.Table1
join b in Db.Table2 on a.Id equals b.Id into c
from d in c.DefaultIfEmpty()
select new { Table1 = a, Table2=d};
The second query will select all entries from the first query where Table2 is null or Table2.Id==1
var result = from obj in partResult
where (obj.Table2 == null || obj.Table2.Id == 2)
select obj.Table1;
This will be composed into a single select statement when the queries execute:
SELECT [t0].[Id]
FROM [dbo].[Table1] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[Id]
FROM [dbo].[Table2] AS [t1]
) AS [t2] ON [t0].[Id] = [t2].[Id]
WHERE ([t2].[test] IS NULL) OR ([t2].[Id] = 2)
if Table 1 has Ids 1, 2, 3, 4, 5, 6 and Table2 has Ids 1, 2, 3, 4 the result will be 1,5,6

Outer join in LINQ Problem

Id like to perform an outer join with the second join statement in this query, I keep getting weird errors! (it must be the 3rd RedBull)
var Objeto = from t in Table1.All()
join su in table2.All() on t.Id equals su.Id
join tab2 in Table1.All() on t.PId equals tab2.Id //<-I want it here
select new
{
t.Field1,
SN = su.Field123,
PTN = tab2.FieldABC
};
Any help would be appreciated.
[Edit] - I neglected to say that I'm using SubSonic 3.0, the bug seems to be with SubSonic.....
Performing an outer join requires two steps:
Convert the join into a group join with into
Use DefaultIfEmpty() on the group to generate the null value you expect if the joined result set is empty.
You will also need to add a null check to your select.
var Objeto = from t in Table1.All()
join su in table2.All() on t.Id equals su.Id
join tab2 in Table1.All() on t.PId equals tab2.Id into gj
from j in gj.DefaultIfEmpty()
select new
{
t.Field1,
SN = su.Field123,
PTN = (j == null ? null : j.FieldABC)
};

Categories

Resources