好的,伙计们。我是菜鸟。我知道(一些)编程、一点 SQL 和很少的 LINQ to SQL。
目标:将嵌套的 ListViews 绑定到 LINQ 生成的匿名类型的 iQueryable。我想使用 LINQ,因为您可以使用 GroupBy 并将嵌套的 ListView 绑定到“it”关键字。
设置:我有一组条件。每组条件都存储在 BillingCodes 表中。每组 BillingCodes 都存储在 BillingGroups 表中。
我有一个自定义对象,用于存储用户选择的每个 BillingGroup 的 ID、名称和 NumCode。
我有一个名为 GroupsList 的对象集合,其中包含用户选择的组列表。
问题 1:我可以遍历 GroupsList 并获取所有 ID。如何为 LINQ to SQL 翻译 SQL 'WHERE ID IN(a string of comma delineated IDs)'?这是最好的方法吗?
问题 2:一旦我有了 BillingGroups 列表,我就需要遍历每个组。对于每个组,我需要遍历 BillingCodes。对于每个 BillingCode,我需要生成一个包含 BillingCode 中所有条件的 WHERE 子句。我提出这样的建议:
for each BillingGroup in BillingGroups
for each BillingCode in BillingGroup.BillingCodes
where1 = "..."
next
next
问题3:这是我不知道的部分。我需要在 LINQ to SQL 中动态创建一个查询。请记住,我不知道会有多少组或每个组中有多少代码。
有2张桌子:
**transactions**
transaction_id
patient_id
svc_date
code
charge
description
**v_patients**
first_name
last_name
patient_id
date_of_birth
insname
active
provider_name
我想象一个看起来像这样的查询:
[Group1] Select MAX(svc_date), patient_id, transaction_id
From (
Select transaction_id, patient_id, svc_date
From transactions join v_patients on patient_id
[Code1] Where code=”” and description contains “” and insurance contains “” and charge >= PriceFloor and charge <= PriceCeiling
UNION
Select transaction_id, patient_id, svc_date
From transactions join v_patients on patient_id
[Code2]Where code=”” and description contains “” and insurance contains “” and charge >= PriceFloor and charge <= PriceCeiling
)
Group By patient_id
UNION
[Group2] Select MAX(svc_date), patient_id, transaction_id
From (
Select transaction_id, patient_id, svc_date
From transactions join v_patients on patient_id
[Code1]Where code=”” and description contains “” and insurance contains “” and charge >= PriceFloor and charge <= PriceCeiling
UNION
Select transaction_id, patient_id, svc_date
From transactions join v_patients on patient_id
[Code2]Where code=”” and description contains “” and insurance contains “” and charge >= PriceFloor and charge <= PriceCeiling
)
Group By patient_id
问题 4:最后,我想将该查询包装在按患者 ID 分组的查询中。以 Select as New With {key, it as transactions, num as count()} 结尾的东西
我通过无休止的阅读和搜索将这些知识拼凑在一起。我将继续寻找答案,但任何帮助将不胜感激。
谢谢。
编辑 - 答案:
这是最终为我工作的代码:
Dim chosenIDs() As Short = (From p In GroupsList _
Select p.ID).ToArray()
GroupMatchListView.DataSource = Nothing
If chosenIDs.Length > 0 Then
Dim db As New AudioRxInternalDataContext
Dim vf As New VersaformDataContext
Dim chosenGroups() As BillingGroup = (db.BillingGroups.Where(Function(m) chosenIDs.Contains(m.ID))).ToArray()
Dim wholeResults As List(Of transaction) = Nothing
For Each chosenGroup As BillingGroup In chosenGroups
Dim groupResults As List(Of transaction) = Nothing
For Each chosenCode As BillingCode In chosenGroup.BillingCodes
Dim codePredicate = PredicateBuilder.True(Of transaction)()
codePredicate = codePredicate.And(Function(i) i.code.Equals(chosenCode.Code))
If Not chosenCode.Description Is Nothing Then codePredicate = codePredicate.And(Function(i) i.description.ToUpper().Contains(chosenCode.Description.ToUpper()))
If Not chosenCode.Insurance Is Nothing Then codePredicate = codePredicate.And(Function(i) i.v_patient.insname.ToUpper().Contains(chosenCode.Insurance.ToUpper()))
If Not chosenCode.PriceFloor Is Nothing Then codePredicate = codePredicate.And(Function(i) i.charge >= chosenCode.PriceFloor)
If Not chosenCode.PriceCeiling Is Nothing Then codePredicate = codePredicate.And(Function(i) i.charge <= chosenCode.PriceCeiling)
If groupResults Is Nothing Then
groupResults = vf.transactions.Where(codePredicate).ToList()
Else
groupResults.AddRange(vf.transactions.Where(codePredicate).ToList())
End If
Next
groupResults = groupResults.GroupBy(Function(r) r.patient_id).SelectMany(Function(g) g.Where(Function(r) r.svc_date = g.Max(Function(a) a.svc_date))).ToList()
If wholeResults Is Nothing Then
wholeResults = groupResults
Else
wholeResults.AddRange(groupResults)
End If
Next
Dim conditionsPredicate = PredicateBuilder.True(Of transaction)()
conditionsPredicate = conditionsPredicate.And(Function(i) i.v_patient.active = "Y")
conditionsPredicate = conditionsPredicate.And(Function(i) i.svc_date >= StartDateBox.Text)
conditionsPredicate = conditionsPredicate.And(Function(i) i.svc_date <= EndDateBox.Text)
If Not OfficeDropDownList.SelectedValue = "Both" Then conditionsPredicate = conditionsPredicate.And( _
Function(i) (If(i.v_patient.provider_name, "").ToUpper().Contains(OfficeDropDownList.SelectedValue.ToUpper())))
wholeResults = wholeResults.Where(conditionsPredicate.Compile()).ToList()
Dim goliath = From f In wholeResults _
Group f By f.v_patient Into Group _
Order By v_patient.last_name, v_patient.first_name, v_patient.date_of_birth _
Select New With {.PatientID = v_patient.patient_id, .LastName = v_patient.last_name, .FirstName = v_patient.first_name, _
.DOB = v_patient.date_of_birth, .Ins = v_patient.insname, .MatchCount = Group.Count(), .Matches = Group}
GroupMatchListView.DataSource = goliath
theMatchesLabel.Text = goliath.Count()
Else
theMatchesLabel.Text = "0"
End If
不要问我为什么用goliath
final 变量。我在深夜创建了那段代码,之前的尝试被命名为david
.
谢谢大家的建议!