0

好的,伙计们。我是菜鸟。我知道(一些)编程、一点 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

不要问我为什么用goliathfinal 变量。我在深夜创建了那段代码,之前的尝试被命名为david.

谢谢大家的建议!

4

1 回答 1

0

编辑:对我感到羞耻:我没有使用 VB,而是使用 c#。但我希望一些答案应该有所帮助......

问题 1:例如,获取名为 Ids 的 int(或字符串)列表或数组并使用

.Where(m => Ids.Contains(m.Id)

如果 ID 列表来自数据库,我认为您必须进行 2 次查询...

问题2:您提供的信息不是很清楚,而是使用

SelectMany(x => blabla)

某个地方应该做的伎俩(但再一次很难这样说)

问题3:这里也不是很清楚:你们工会在同一个群体中的利益是什么?如果差异只是代码,为什么不使用问题1的系统?

要构建“动态查询”,我只能说 IQueryable 可以“按需”构建,例如经典代码

var query = blabla;
if (searchCriterion.Name != null)
  query = query.Where(m => m.Name == searchCriterion.Name);

问题 4:我使用“ToDictionary()”扩展,因为您似乎需要 KeyValuePair,但它们当然是其他方式。

GroupBy(m => m.TransactionId).ToDictionary(m => m.Key, m => m.Count)

但是......如果你可以更具体一点,也许;)

编辑问题 4: 没读好,而是类似的东西

GroupBy(m => m.TransactionId).Select(g => new {
patientId = g.Key,
transaction = g.SelectMany(p => p.Transactions),
num = g.Count());
于 2012-04-05T09:52:18.580 回答