I have a SQL database that I'm using LINQ to connect to (LINQ To SQL) and a local set of XML data (in a dataset). I need to perform an outer left join on the SQL table "tblDoc" and dataset table "document" on the keys "tblDoc:sourcePath, document:xmlLink". Both keys are unfortunately strings. The code I have below doesn't return any results and I've tried a few variations but my LINQ skills are limited. Does anyone have any suggestions or alternate methods to try?
DataColumn xmlLinkColumn = new DataColumn(
"xmlLink",System.Type.GetType("System.String"));
xmlDataSet.Tables["document"].Columns.Add(xmlLinkColumn);
foreach (DataRow xmlRow in xmlDataSet.Tables["document"].Rows)
{
xmlRow["xmlLink"] = (string)xmlRow["exportPath"] +
(string) xmlRow["exportFileName"];
}
var query =
from t in lawDataContext.tblDocs.ToList()
join x in xmlDataSet.Tables["Document"].AsEnumerable()
on t.SourceFile equals (x.Field<string>("xmlLink"))
select new
{
lawID = t.ID,
xmlID = x == null ? 0 : x.Field<int>("id")
};
foreach (var d in query.ToArray())
{
Debug.WriteLine(d.lawID.ToString() + ", " + d.xmlID.ToString());
}
The join clause produces standard inner join behavior. To get an outer join, you need to use the DefaultIfEmpty() extension method:
var query = from t in lawDataContext.tblDocs.ToList()
join x in xmlDataSet.Tables["Document"].AsEnumerable()
on t.SourceFile equals (x.Field<string>("xmlLink"))
into outer
from o in outer.DefaultIfEmpty()
select new
{
lawID = t.ID,
xmlID = o == null ? 0 : o.Field<int>("id")
};
Related
I am trying to convert below SQL query to LINQ,
SELECT
TD.*, RD.*
FROM
dbo.TransactionDetail TD
INNER JOIN
dbo.Measure M ON M.InternalID = TD.MetricCode
LEFT OUTER JOIN
(SELECT
tmp.ID, tmp.ReportingDate, 1 AS Match
FROM
tmp) AS RD ON RD.ID = M.Frequency
AND RD.ReportingDate = TD.ReportingDate
WHERE
RD.Match IS NULL
AND TD.BatchID = 'e07f9855-b286-4406-9189-5cfb2a7914c8'
My Linq query looks like below,
Update : Added td and rd definition
var rd = (from tt in result
select new { ID = tt.Id, tt.ReportingDate });
// inner join
var td = TransactionDetail.Join(
MesureTb,
t => t.MetricCode,
m => m.InternalId,
(t, m) => new
{
t.Id,
t.RowAction,
t.BatchId,
t.TrustCode,
t.MetricCode,
t.ReportingDate,
t.Value,
t.UpperBenchmark,
t.LowerBenchmark,
m.InternalId,
Frequency = m.Frequency
});
var result2 = from a in td//inner join already done in previous step
join b in rd
on new { ReportingDate = (DateTime)a.ReportingDate, ID = a.Frequency } equals new { b.ReportingDate, b.ID } into j
from b in j.DefaultIfEmpty()
where b == null && a.BatchId == batchId
select a.Id;
Could someone help me how I can write this in a simple and efficient way? It is basically selecting the Non matching rows where Match = null
Update :
The TD in Linq contains list of reporting dates ranging from 2009 to 2021
The Right table RD is a lookup table which has date values between 2010 to 2020
Expected out put : The query should return the values from TD table which has Reporting date < 2010 and > 2020
Example below :
Expected Output : As in above screen shot, I need values which have Match as NULL.
I hope this explains what I am trying to achieve.
Any help is appreciated.
Thanks in advance.
I have a linq query with a where clause as below
var ExistingGroupDataSource = (from ppatg in dbContext.XXXXXXXXX
join pd1 in dbContext.XXXXXXXXXXX on ppatg.ScheduleID equals pd1.ScheduleID
where pd1.GroupID == null
select
new
{
FinishPDI = pd1.ProductionDateID,
FinishingDate = pd1.WorkFlowDate,
ppatg.GroupName,
ppatg.PNTGroupID
});
In the database GroupID is an int that can be null. The linq query returns rows without the filtered where clause but none when I include the where clause. There are null values in the GroupId column in the database.
It is definitely this statement that produces no results. All the literature on the subject online says that this is equivalent to
pd1.GroupID is null // in sql
I am getting results that contradict this
Sql code is
select pd1.ProductionDateID as FinishPDI, pd1.WorkflowDate as FinishingDate,GroupName ,PNTGroupId
from XXXXXXXXXXXX
inner join XXXXXXXXXXXX pd1 on
XXXXXXXXXXXX.ScheduleId = pd1.ScheduleID
where pd1.GroupID is null
You can combine your where with the join, which should give you the expected results:
var ExistingGroupDataSource = (from ppatg in dbContext.XXXXXXXXX
join pd1 in dbContext.XXXXXXXXXXX.Where(p => !p.GroupId.HasValue) on ppatg.ScheduleID equals pd1.ScheduleID
select
new
{
FinishPDI = pd1.ProductionDateID,
FinishingDate = pd1.WorkFlowDate,
ppatg.GroupName,
ppatg.PNTGroupID
});
Folks,
Trying to convert the following SQL-Server Command to LINQ. I have verified the SQL runs correctly via SSMS.
select top 100 tts.* from tblLCState tts
INNER JOIN
(SELECT fldLCID, MAX(fldStateDate) AS Statedate
FROM tblLCState
GROUP BY fldLCID) grptts
ON tts.fldLCID = grptts.fldLCID
AND tts.fldStateDate = grptts.Statedate
where fldLCStateCode = 1
order by fldStateDate desc
I am confused how to join the table tblLCState to the select statement. My attempt at the LNIQfollows:
from tRow in tblLCState
join irow2 in (from iRow in tblLCState
group iRow by iRow.fldLCID into g
select new {fldLCID = g.Key, MaxStateDate = (from t2 in g select t2.fldStateDate).Max()} )
on ((tRow.fldStateDate = irow2.MaxStateDate) and (tRow.fldLCID = irow2.g.fldLCID))
The error is on the and operator in the on clause saying that a ) was expected. I have not attempted the where/order/top 100 at this point. Just have spent much time looking for the join with no luck on this form or any other. I have seen many posts to join on another table but unfortunately I don't have this luxury.
Any help would be appreciated.
Thanks
Tom D.
LINQ
var result = (from tRow in tblLCState
join irow2 in (from iRow in tblLCState
group iRow by iRow.fldLCID into g
select new { fldLCID = g.Key, MaxStateDate = g.Max(k => k.fldStateDate) })
on new { StateDate = tRow.fldStateDate, tRow.fldLCID } equals new { StateDate = irow2.MaxStateDate, irow2.fldLCID }
select tRow);
I was trying to replace SQL code with LINQ in order to migrate in to MVC ,but i don't know how to use subquery in LINQ.As of now i have replaced inner sql query with LINQ,i would like to know how to do with outer query.
Following is the SQL query
SELECT
DISTINCT GP_REGION.REGION_MAIN Region_Code,
R1.REGION_NAME
FROM
GP_REGION
INNER JOIN GP_REGION R1 ON GP_REGION.REGION_MAIN = R1.REGION_CODE
WHERE
GP_REGION.REGION_HAS_DATA = 'Y'
AND
GP_REGION.REGION_MAIN IN
(
SELECT
DISTINCT AR.BRANCH_CODE
FROM
PORTAL.UA_APPLN_ROLE AR
INNER JOIN PORTAL.UA_GROUP G ON AR.GROUP_CODE = G.GROUP_CODE
WHERE
G.USER_ID = '" + Global.UserId() + "' AND AR.APPLICATION_ID = '" + ApplicationId + "'
)
ORDER BY
GP_REGION.REGION_MAIN
Here the inner query i have replaced as shown below by using following LINQ
var regions = from p in db3.UA_APPLN_ROLE.AsEnumerable()
join i in db3.UA_GROUP.AsEnumerable()
on p.GROUP_CODE equals i.GROUP_CODE
where
i.USER_ID == Global.UserId()
&&
p.APPLICATION_ID == ConfigurationManager.AppSettings["ApplicationId"]
select new
{
branchcode = p.BRANCH_CODE
};
But i would like to know the outer sql query how can i replace and join with existing LINQ code i wrote
You combine the subquery into the main query as follows:
var efQuery = from gp in db3.GP_REGION
join r1 in db3.GP_REGION on gp.REGION_MAIN equals r1.REGION_CODE
where regions.Contains(gp.REGION_MAIN)
&& gp.REGION_HAS_DATA = "Y"
select new
{
Region_Code = gp.REGION_MAIN,
Region_Name = r1.REGION_NAME
};
var queryResult = efQuery.Distinct().OrderBy(x => x.Region_Code);
You can speed the processing up a bit by using .AsNoTracking(), e.g. db3.GP_REGION.AsNoTracking().
In general it's a good idea to monitor the generated SQL query to avoid situations where it looks simple in code, but is transformed into bad SQL.
But in my opinion the advantages of having the query a first class member in your code (compared to SQL in strings) outweigh the sometimes non-intuitive generated SQL.
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]