Linq with Multiple Joins - c#

I'm attempting to translate the following SQL statement to Linq and am having trouble with the multiple joins- I seem to be missing something.
SELECT DISTINCT
Test1 = Table1.Column1,
Test2 = 1,
Test3 = Table1.Column2,
Test4 = Table1.Column5,
Test5 = Table1.Column6
FROM Table1
LEFT JOIN Table2 ON Table1.Column1 = Table2.Column1
INNER JOIN Table3 ON Table1.Column3 = Table3.Column3
WHERE Table3.Column4 IN (1,2,6)
Here's the Linq so far:
var TestQuery = Table1_Collection.Select(x => new
{
Test1 = Table1.Column1,
Test2 = 1,
Test3 = Table1.Column2,
Test4 = Table1.Column5,
Test5 = Table1.Column6
})
[joins go here]
.Where("where stuff goes here");
Any ideas? I'm not so much seeking assistance with the .Where as I am the joins. I'm not sure about the formatting with the method syntax.

Here you go:
var results = Table3_Collection
.Where(i => column4s.Contains(i.Column4))
.Join(Table1_Collection, i => i.Column3, i => i.Column3, (i, j) => j)
.Join(Table2_Collection, i => i.Column1, i => i.Column1, (i, j) => i)
.Distinct(comparer);
In your original SQL query you weren't using selecting any columns from Table2, so you could omit that join. I included it above, but please feel free to remove it.
Also, your C# example didn't have Distinct, but I included it for you as it was in your original SQL query, and is most likely your intent. And, please, don't forget to implement your own IEqualityComparer. Here is an example of one:
class Table1Comparer : IEqualityComparer<Table1>
{
public bool Equals(Table1 x, Table1 y)
{
return x.Column1 == y.Column1
&& x.Column2 == y.Column2
&& x.Column3 == y.Column3
&& x.Column4 == y.Column4
&& x.Column5 == y.Column5
&& x.Column6 == y.Column6;
}
public int GetHashCode(Table1 obj)
{
return obj.GetHashCode();
}
}

try this example, I hope you help
class Table1
{
public int Id1 { get; set; }
public string Column1 { get; set; }
}
class Table2
{
public int Id2 { get; set; }
public string Column2 { get; set; }
}
class Table3
{
public int Id3 { get; set; }
public string Column3 { get; set; }
}
static void Main(string[] args)
{
var table1 = new List<Table1>();
var table2 = new List<Table2>();
var table3 = new List<Table3>();
for (int i = 0; i < 10; i++)
{
table1.Add(new Table1 { Id1 = i, Column1 = "column1_table1_" + i });
table2.Add(new Table2 { Id2 = i, Column2 = "column2_table2_" + i });
table3.Add(new Table3 { Id3 = i, Column3 = "column3_table3_" + i });
}
var table1JoinTable2 = table1.Join(table2, t1 => t1.Id1, t2 => t2.Id2, (t1, t2) => new { Id = t1.Id1, Column1 = t1.Column1, Column2 = t2.Column2 } );
var table1JoinTable2JoinTable3 = table1JoinTable2.Join(table3, t12 => t12.Id, t3 => t3.Id3, (t12, t3) => new { Id = t12.Id, Column1 = t12.Column1, Column2 = t12.Column2, Column3 = t3.Column3 });
var result1 = table1JoinTable2JoinTable3.Single(t123 => t123.Id == 1);
Console.WriteLine("Id={0} C1={1} C2={2} C3={3}", result1.Id, result1.Column1, result1.Column2, result1.Column3);
// prints "Id=1 C1=column_table1_1 C2=column_table2_1 C3=column_table3_1"
}

Here is an example of your original SQL statement in LINQ query syntax.
List<int> vals = new List<int> {1,2,6};
var qry = from rec1 in Table1
join rec2 in Table2 on rec1.Column1 equals rec2.Column2 into ljT2
from rec2 in ljT2.DefaultIfEmpty() //Handle left join
join rec3 in Table3 on rec1.Column1 equals rec3.Column3
where vals.Contains(rec3.Column4)
select new {
Test1 = rec1.Column1,
Test2 = 1,
Test3 = rec2 == null?null:rec2.Column2, //Must allow for rec2 to be null
Test4 = rec3.Column5,
Test5 = rec3.Column6
}
qry = qry.Distinct();

Related

LINQ with joins and group generates enormous query and is slow

My Entity structure is as follows:
public class DisbursementItem
{
public int DisbursementNumber;
public int IDDisbursementItem;
public int IDReceiptItem;
public decimal Amount;
public decimal MeasureUnit;
public decimal PricePerMU;
public decimal PriceTotal;
public Disbursement Disbursement_IDDisbursement;
public int IDDisbursementNumber;
}
public class Disbursement
{
public int DisbursementNumber;
DateTime date;
DisbursementType DType;
string Note;
string Subscriber;
Subscriber SubscriberModel;
string ItemType;
int ProcessNumber;
}
public class Subscriber
{
public string Name
public string Address;
public string City;
}
public class DisbursementDescription
{
public int IDDisbursementItem;
public string Description;
}
public class Receipt
{
public int IDReceiptItem;
public int ItemNumber;
}
public class StorageCard
{
public int ItemNumber;
public string StorageCardGroup;
public string StorageCardName;
}
And my EF6 LINQ query is:
DateTime from;
DateTime to;
var result = context.DisbursementItem
.Where(x => x.Disbursement_IDDisbursement.Date <= to && x.Disbursement_IDDisbursement.Date >= from)
.Join(context.DisbursementDescription, di => di.IDDisbursementItem, dd => dd.IDDisbursementItem, (di, dd) => new {di = di, desc = dd.Description})
.Join(context.Receipt, x => x.di.IDReceiptItem, r => r.IDReceiptItem, (x, r) => new { di = x.di, desc = x.desc, r = r })
.Join(context.StorageCard, x => x.r.ItemNumber, sc => sc.ItemNumber, (x, sc) => new { di = x.di, desc = x.desc, r = x.r, sc = sc})
.GroupBy(g => new {g.di.DisbursementNumber, g.sc.ItemNumber, g.di.MeasureUnit})
.Select(x => new
{
Date = x.FirstOrDefault().di.Disbursement_IDDisbursement.Date,
DisbursementNumber = x.Key.DisbursementNumber,
DType = x.FirstOrDefault().di.Disbursement_IDDisbursement.DType,
Note = x.FirstOrDefault().di.Disbursement_IDDisbursement.Note,
Subscriber = x.FirstOrDefault().di.Disbursement_IDDisbursement.Subscriber,
SubscriberName = x.FirstOrDefault().di.Disbursement_IDDisbursement.SubscriberModel.Name,
SubscriberAddress = x.FirstOrDefault().di.Disbursement_IDDisbursement.SubscriberModel.Address,
SubscriberCity = x.FirstOrDefault().di.Disbursement_IDDisbursement.SubscriberModel.City,
ItemNumber = x.FirstOrDefault().sc.ItemNumber,
StorageCardGroup = x.FirstOrDefault().sc.StorageCardGroup,
StorageCardName = x.FirstOrDefault().sc.StorageCardName,
Amount = x.Sum(y => y.di.Amount),
PricePerMU = x.FirstOrDefault().di.PricePerMU,
PriceTotal = x.Sum(y => y.di.PriceTotal),
MeasureUnit = x.Key.MeasureUnit
Desc = x.FirstOrDefault().desc,
})
SELECT
di.Date,
di.DisbursementNumber,
d.DType,
d.Note,
d.Subscriber,
subs.Name,
subs.Address,
subs.City,
sc.ItemNumber,
sc.StorageCardGroup,
sc.StorageCardName,
Sum(di.Amount) as Amount,
di.PricePerMU,
Sum(di.PriceTotal) as PriceTotal,
di.MeasureUnit,
dd.Description
FROM
DisbursementItem as di
INNER JOIN Disbursement as d
ON di.IDDisbursementNumber = d.DisbursementNumber
INNER JOIN Receipt as r
ON di.IDReceiptItem = r.IDReceiptItem
INNER JOIN StorageCard as sc
ON r.ItemNumber = sc.ItemNumber
INNER JOIN DisbursementDescription dd
ON di.IDDisbuzrsementItem = dd.IDDisbursementItem
WHERE
di.Date <= ... and di.Date >= ...
GROUP BY
di.DisbursementNumber, sc.ItemNumber, di.MeasureUnit
That is the query in SQL that I want to achieve in EF
This query can take over a minute for a few hundred rows. How can I optimize it? I suspect the multiple joins is a problem and maybe also the Sum of some fields.
Also the database schema cannot be modified.
The query it generate is enormous. It's like a SELECT in SELECT in SELECT for like 40 times.
Easiest way is to add all fields which are needed for result to grouping key. Rewritten query to Query syntax for readability and maintainability:
DateTime from;
DateTime to;
var query =
from di in context.DisbursementItem
where di.Disbursement_IDDisbursement.Date <= to && di.Disbursement_IDDisbursement.Date >= from
join dd in context.DisbursementDescription on di.IDDisbursementItem equals dd.IDDisbursementItem
join r in context.Receipt on di.IDReceiptItem equals r.IDReceiptItem
join sc in context.StorageCard on r.ItemNumber equals sc.ItemNumber
group di by new
{
di.DisbursementNumber,
sc.ItemNumber,
di.MeasureUnit,
di.Disbursement_IDDisbursement.Date,
di.Disbursement_IDDisbursement.DType,
di.Disbursement_IDDisbursement.Note,
Subscriber = di.Disbursement_IDDisbursement.Subscriber,
SubscriberName = di.Disbursement_IDDisbursement.SubscriberModel.Name,
SubscriberAddress = di.Disbursement_IDDisbursement.SubscriberModel.Address,
SubscriberCity = di.Disbursement_IDDisbursement.SubscriberModel.City,
sc.ItemNumber,
sc.StorageCardGroup,
sc.StorageCardName,
di.PricePerMU,
Desc = dd.Description
} into g
select new
{
g.Key.Date,
g.Key.DisbursementNumber,
g.Key.DType,
g.Key.Note,
g.Key.Subscriber,
g.Key.SubscriberName,
g.Key.SubscriberAddress,
g.Key.SubscriberCity,
g.Key.ItemNumber,
g.Key.StorageCardGroup,
g.Key.StorageCardName,
g.Key.PricePerMU,
g.Key.MeasureUnit,
g.Key.Desc,
Amount = g.Sum(x => x.Amount),
PriceTotal = g.Sum(x => x.PriceTotal)
}
you could try some kind of multithreading
the query could be splitted in parts and each part assigned to a task. in here you should find something useful (parallel section):
https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks?view=net-6.0

SQL to LINQ handling Match in Left outer JOIN

I am trying to convert below SQL to LINQ query and I am stuck with filtering results using the Match in Left outer Join.
SELECT #batchID , IQ1.ID, #environment , 'IRD', IQ1.ReportingDate, IQ1.Match
FROM (
SELECT TD.*, RD.Match
FROM TransactionDetail TD
INNER JOIN .dbo.Measure M ON M.InternalID = TD.MetricCode-- and TD.BatchID = 'e07f9855-b286-4406-9189-5cfb2a7914c8'
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 = #batchID AND
NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'NRD') AND
NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'RDP') AND
NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'RDF')
) AS IQ1
I have so far achieved below,
// Prepare data for left outer join
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
});
// left outer join
var failureTransactionDetail = (from p in td
join q in rd on new { ReportingDate = (DateTime)p.ReportingDate, ID = p.Frequency } equals new { q.ReportingDate, q.ID }
into LJ
//select new { p.Id, p.BatchId, p.ReportingDate, RD = q.ReportingDate, q.ID, p.Frequency });
from value in LJ.DefaultIfEmpty()
//where p.BatchId == batchId
select new {p.BatchId, p.Id, Match = 1, p.ReportingDate } into DJ
// LEFT OUTER JOIN
where DJ.BatchId == batchId
////&& DJ.Match == 0
&& !(TransactionDetailFailureReasons.Any(m => m.TransactionDetailId == DJ.Id && m.TransactionFailureReasonId == "NRD"))
&& !(TransactionDetailFailureReasons.Any(m => m.TransactionDetailId == DJ.Id && m.TransactionFailureReasonId == "RDP"))
&& !(TransactionDetailFailureReasons.Any(m => m.TransactionDetailId == DJ.Id && m.TransactionFailureReasonId == "RDF"))
select new { DJ.Id, DJ.ReportingDate, DJ.BatchId } );
My question being how i can achieve similar result as 1 AS Match does in SQL in Linq.
Could someone please guide me? Currently the SQL query returns 2 results based on Match value as null, but the LInq returns 8 results since it is not filtering the Match on Left join.
Any help is much appreciated.
Thanks in advance.
I'm just taking a stab at helping you out here because the question is a little unclear. But just comparing your sql statement to your linq query I can see that you may be trying to filter where: RD.Match IS NULL? If that assumption is correct then there is problem with your linq query.
Given the following objects:
public class TransactionDetail
{
public TransactionDetail(int id,
int batchId,
int metricCode,
DateTime reportingDate)
{
Id = id;
BatchId = batchId;
MetricCode = metricCode;
ReportingDate = reportingDate;
}
public int Id { get; }
public int BatchId { get; }
public int MetricCode { get; }
public DateTime ReportingDate { get; }
}
public class Measure
{
public Measure(int internalId,
int frequency)
{
InternalId = internalId;
Frequency = frequency;
}
public int InternalId { get; }
public int Frequency { get; }
}
public class Tmp
{
public Tmp(int id,
DateTime reportingDate)
{
Id = id;
ReportingDate = reportingDate;
}
public int Id { get; }
public DateTime ReportingDate { get; }
}
Sample Code:
static void Main(string[] args)
{
var transactionDetails = new List<TransactionDetail>
{
new TransactionDetail(id: 1, batchId: 1, metricCode: 1, reportingDate: new DateTime(2019, 1, 1)),
new TransactionDetail(id: 2, batchId: 1, metricCode: 2, reportingDate: new DateTime(2019, 1, 1))
};
var matches = new List<Measure>
{
new Measure(internalId: 1, frequency: 1),
new Measure(internalId: 2, frequency: 3)
};
var temporaryList = new List<Tmp>
{
new Tmp(1, new DateTime(2019, 1, 1)),
};
var transDetails = transactionDetails.Join(
matches,
t => t.MetricCode,
m => m.InternalId,
(t, m) => new
{
t.Id,
t.BatchId,
t.MetricCode,
t.ReportingDate,
m.InternalId,
m.Frequency
})
.ToList();
var failureTransactionDetail = transDetails
.GroupJoin(temporaryList,
trandetail => new { trandetail.ReportingDate, Id = trandetail.Frequency },
tmp => new { tmp.ReportingDate, tmp.Id },
(trandetail, tmp) => new { trandetail, tmp })
.SelectMany(t => t.tmp.DefaultIfEmpty(), (t, value) => new { t, value, Matches = 1 })
.Where(arg => !arg.t.tmp.Any());
Console.WriteLine(JsonConvert.SerializeObject(failureTransactionDetail, Formatting.Indented));
Console.ReadLine();
}
Examine the output and you'll see that you don't need Match = 1. .Where(arg => !arg.t.tmp.Any()) would be the equivalent to RD.Match IS NULL in your sql query.
Hope that puts you in the right direction.

LINQ Join usage data from two data sets into one

What I have:
Two lists of the following model:
int SubscriptionId
int ItemId
double Usage
double EffectiveRate
string ResourceName
string UnitOfMeasure
The first contains usage data of the last month like this:
SubscriptionId ItemId Usage EffectiveRate ResourceName UnitOfMesaure
_________________________________________________________________________
1 1 2 2,75 R1 U1
1 2 3 1,50 R2 U2
The seconds contains usage data of the current month like this:
SubscriptionId ItemId Usage EffectiveRate ResourceName UnitOfMesaure
_________________________________________________________________________
1 1 5 2,75 R1 U1
1 3 2 1,50 R3 U3
What I want:
This should be merge in a list like this:
SubscriptionId ItemId UsageThis UsageLast EffRate ResName UOM
_________________________________________________________________________
1 1 5 2 2,75 R1 U1
1 2 0 3 1,50 R2 U2
1 3 2 0 1,50 R3 U3
What I have:
//data for both months available
if (resourcesThisMonth.Any() && resourcesLastMonth.Any())
{
//join both months
resources = from resourceLastMonth in resourcesLastMonth
join resourceThisMonth in resourcesThisMonth
on new { resourceLastMonth.SubscriptionId, resourceLastMonth.ItemId } equals new { resourceThisMonth.SubscriptionId, resourceThisMonth.ItemId }
select new Resource
{
SubscriptionId = resourceThisMonth.SubscriptionId,
ItemId = resourceThisMonth.ItemId,
UsageThisMonth = resourceThisMonth.Usage,
UsageLastMonth = resourceLastMonth.Usage,
EffectiveRate = resourceThisMonth.EffectiveRate,
ResourceName = resourceThisMonth.ResourceName,
UnitOfMeasure = resourceThisMonth.UnitOfMeasure
};
//resources only last month available
var resourcesOnlyLastMonth = resourcesLastMonth.Where(r => !resourcesThisMonth.Where(s => s.ItemId == r.ItemId && s.SubscriptionId == r.SubscriptionId).Any())
.Select(r => new Resource
{
SubscriptionId = r.SubscriptionId,
ItemId = r.ItemId,
UsageThisMonth = 0.0,
UsageLastMonth = r.Units,
EffectiveRate = r.EffectiveRate,
ResourceName = r.ResourceName,
UnitOfMeasure = r.UnitOfMeasure
});
//resources only this month available
var resourcesOnlyThisMonth = resourcesThisMonth.Where(r => !resourcesLastMonth.Where(s => s.ItemId == r.ItemId && s.SubscriptionId == r.SubscriptionId).Any())
.Select(r => new Resource
{
SubscriptionId = r.SubscriptionId,
ItemId = r.ItemId,
UsageThisMonth = r.Usage,
UsageLastMonth = 0.0,
EffectiveRate = r.EffectiveRate,
ResourceName = r.ResourceName,
UnitOfMeasure = r.UnitOfMeasure
});
//union data
resources = resources.Union(resourcesOnlyLastMonth);
resources = resources.Union(resourcesOnlyThisMonth);
}
//data for last month available
else if (resourcesLastMonth.Any())
{
resources = from resource in resourcesLastMonth
select new Resource
{
SubscriptionId = resource.SubscriptionId,
ItemId = resource.ItemId,
UsageThisMonth = 0.0,
UsageLastMonth = resource.Usage,
EffectiveRate = resource.EffectiveRate,
ResourceName = resource.ResourceName,
UnitOfMeasure = resource.UnitOfMeasure
};
}
//data for this month available
else if (resourcesThisMonth.Any())
{
resources = from resource in resourcesThisMonth
select new Resource
{
SubscriptionId = resource.SubscriptionId,
ItemId = resource.ItemId,
UsageThisMonth = resource.Usage,
UsageLastMonth = 0.0,
EffectiveRate = resource.EffectiveRate,
ResourceName = resource.ResourceName,
UnitOfMeasure = resource.UnitOfMeasure
};
}
//no data available
else
{
resources = new List<Resource>();
}
Problem:
This is very much code - should be less, any possible solutions failed so far
Thanks for helping!
public class ExampleClass
{
public int Id1 { get; set; }
public int Id2 { get; set; }
public int Usage { get; set; }
public int UsageThis { get; set; }
public int UsageLast { get; set; }
}
List<ExampleClass> listThisMonth = new List<ExampleClass>
{
new ExampleClass{Id1=1, Id2=1,Usage=7, UsageThis=1, UsageLast=0},
new ExampleClass{Id1=2, Id2=2,Usage=4, UsageThis=2, UsageLast=0},
new ExampleClass{Id1=3, Id2=3,Usage=1, UsageThis=3, UsageLast=0},
};
List<ExampleClass> listLastMonth = new List<ExampleClass>
{
new ExampleClass{Id1=1, Id2=1,Usage=3, UsageThis=1, UsageLast=1},
new ExampleClass{Id1=4, Id2=4,Usage=3, UsageThis=4, UsageLast=3},
new ExampleClass{Id1=2, Id2=2,Usage=1, UsageThis=8, UsageLast=6},
};
var result = listThisMonth.Select(a=>new {value=a, list=1})
.Union(listLastMonth.Select(a => new { value = a, list = 2 }))
.GroupBy(a => new { Id1 = a.value.Id1, Id2 = a.value.Id2 })
.Select(x => new ExampleClass
{
Id1 = x.Key.Id1,
Id2 = x.Key.Id2,
UsageThis = x.Any(o => o.list == 1) ? x.First(o => o.list == 1).value.Usage : 0,
UsageLast = x.Any(o => o.list == 2) ? x.First(o => o.list == 2).value.Usage : 0,
Usage = x.Sum(o=>o.value.Usage)
}).ToList();
//id1 id2 current last sum
//1 1 7 3 10
//2 2 4 1 5
//3 3 1 0 1
//4 4 0 3 3
It looks to me that what you're looking for is a full outer join. Unfortunately, it looks like LINQ doesn't have a construct for that. So, there are a few options: LINQ - Full Outer Join
For your scenario, it looks like you have some redundant code. You should be able to do the union using two outer joins to get the correct result set. For example:
// Left join the current month with the last month
var currentMonth =
from current in resourcesThisMonth
join last in resourcesLastMonth on new { current.SubscriptionId, current.ItemId } equals new { last.SubscriptionId, last.ItemId } into outer
from o in outer.DefaultIfEmpty()
select new Resource
{
SubscriptionId = current.SubscriptionId,
ItemId = current.ItemId,
UnitsThisMonth = current.Units,
UnitsLastMonth = o?.Units ?? 0, // Replace NULL with 0
EffectiveRate = current.EffectiveRate,
ResourceName = current.ResourceName,
UnitOfMeasure = current.UnitOfMeasure
};
// Reverse of the first join. Last month LEFT JOIN Current month
var lastMonth =
from last in resourcesLastMonth
join current in resourcesThisMonth on new { last.SubscriptionId, last.ItemId } equals new { current.SubscriptionId, current.ItemId } into outer
from o in outer.DefaultIfEmpty()
select new Resource
{
SubscriptionId = last.SubscriptionId,
ItemId = last.ItemId,
UnitsThisMonth = o?.Units ?? 0, // Replace NULL with 0
UnitsLastMonth = last.Units,
EffectiveRate = o?.EffectiveRate ?? last.EffectiveRate,
ResourceName = o?.ResourceName ?? last.ResourceName,
UnitOfMeasure = o?.UnitOfMeasure ?? last.UnitOfMeasure
};
// Union them together to get a full join
var resources = currentMonth.Union(lastMonth);

update with LINQ, and in operator select

Im tryig to transform a SP, into a linq query
This is my SP right now :
UPDATE PatientAlertsSummary
SET IsViewed =1
WHERE PatientID IN (SELECT PatientID FROM PatientTherapist WHERE TherapistID=#TherapistID)
I tried to make a query linq code and this is (so far) my linq query:
I came across some difficulty with doing this
var query = from pas in context.PatientAlertsSummaries
where pas.PatientID.Contains(from pt in context.PatientTherapists where pt.TherapistID == therapistid )
select pas;
foreach (var item in query)
{
item.IsViewed = true;
}
how can I make it right ?
You could change the query to join on the tables to retrieve the results you want, then update the records accordingly:
var query = from pas in context.PatientAlertsSummaries
join pt in context.PatientTherapists on pas.PatientID equals pt.PatientID
where pt.TherapistID == therapistid
select pas;
foreach (var item in query)
{
item.IsViewed = true;
}
Obviously this is untested and based on your current sql / linq query.
You can do something like this:
public class PatientAlertsSummary
{
public bool IsViewed;
public int PatientID;
}
public class PatientTherapist
{
public int PatientID;
public int TherapistID;
}
public void UpdateIsViewed(PatientAlertsSummary summary)
{
summary.IsViewed = true;
}
[TestMethod]
public void Test1()
{
//UPDATE PatientAlertsSummary
//SET IsViewed =1
//WHERE PatientID IN (SELECT PatientID FROM PatientTherapist WHERE TherapistID=#TherapistID)
var therapistId = 1;
var patientAlertsSummaries = new List<PatientAlertsSummary>() {
new PatientAlertsSummary(){PatientID = 1},
new PatientAlertsSummary(){PatientID = 2},
new PatientAlertsSummary(){PatientID = 3}
};
var PatientTherapists = new List<PatientTherapist>() {
new PatientTherapist(){PatientID = 1 , TherapistID = 1},
new PatientTherapist(){PatientID = 2 , TherapistID = 1},
new PatientTherapist(){PatientID = 3, TherapistID = 2}
};
var updatedPatinets1 = PatientTherapists.
Where(o => o.TherapistID == therapistId).
Join(patientAlertsSummaries,
patientTherapist => patientTherapist.PatientID,
patientAlertsSummary => patientAlertsSummary.PatientID,
(o, p) =>
{
UpdateIsViewed(p);
return p;
}).ToList();
}

How to order data with matching ID from another table using linq?

So I have 2 tables and I am trying to retrieve the data from table 1, however I need it sorting. Table 1 contains an ID from table 2 which refers to a string, I need to order the table 1 data by this string in table 2.
For example...
TABLE 1
COL_A | COL_B | COL_C
1 | 3 | sample
2 | 1 | test
3 | 2 | string
TABLE 2
COL_A | COL_B
1 | my name
2 | his name
3 | her name
So I need to order all the data in TABLE 1 by COL_B, but order it by the string in TABLE 2 where the ID matches TABLE 1 COL_B with TABLE 2 COL_A.
How can I do this using LINQ?
You basically need to join two tables, then order by TABLE2.COL_B, then select TABLE1.
Below linq expression should work.
from t1 in TABLE1
join t2 in TABLE2 on t1.COL_B equals t2.COL_A
orderby t2.COL_B
select t1
I have given the solution below
class Table1
{
public int IdA { get; set; }
public int IdB { get; set; }
public string Table1StrValue { get; set; }
}
class Table2
{
public int IdA { get; set; }
public string Table2StrValue { get; set; }
}
var table1List = new List<Table1>()
{
new Table1 {IdA = 1, IdB = 3, Table1StrValue = "sample"},
new Table1 {IdA = 2, IdB = 1, Table1StrValue = "test"},
new Table1 {IdA = 3, IdB = 2, Table1StrValue = "string"},
};
var table2List = new List<Table2>()
{
new Table2 {IdA = 1, Table2StrValue = "my Name"},
new Table2 {IdA = 2, Table2StrValue = "his Name"},
new Table2 {IdA = 3, Table2StrValue = "her Name"},
};
var result = from table2 in table2List
join table1 in table1List on table2.IdA equals table1.IdA
orderby table2.Table2StrValue
select new {table2.IdA, table2.Table2StrValue, table1.Table1StrValue};
So I wrote this, and used Musa to help finish it off.. I think it's what you want
public class table1
{
public int a;
public int b;
public string c;
}
public class table2
{
public int a;
public string b;
}
void Main()
{
List<table1> table1 = new List<table1>()
{
new table1(){ a=1,b=2, c="RAWR"},
new table1(){ a=2,b=4, c="DERP"},
new table1(){ a=3,b=1, c="FOO"},
new table1(){ a=4,b=3, c="BAR"},
};
List<table2> table2 = new List<table2>()
{
new table2(){a=1,b="A"},
new table2(){a=2,b="B"},
new table2(){a=3,b="D"},
new table2(){a=4,b="C"},
};
var something = from t1 in table1
join t2 in table2 on t1.b equals t2.a
orderby t2.b
select t1;
Console.WriteLine (something);
}
This is probably the shortest way.
var ret = TABLE1.Join(TABLE2, a => a.COL_A, b => b.COL_A, (a, b) => new {COL_C = b.COL_C)}).OrderBy(s => s.COL_C);

Categories

Resources