使用子查询中的动态字段将两表存在查询从 SQL 转换为 Linq
我正在尝试查询旧的 Access 数据库表并将它们与 SQL Server 表进行比较。 它们通常没有主键,或者它们具有在九十年代具有某种用途的额外字段等,或者新表具有新字段等。
我需要查找记录 - 基于运行时指定的一组字段- 它们在一张表中,但不在另一张表中。
因此,当我比较不同表中的数据时,我总是在 SQL 中执行这种查询:
dim fields_i_care_about as string = "field1, field2, field3"
'This kind of thing gets set by a caller, can be any number of fields, depends on the
'table
dim s as string= ""
dim flds = fields_i_care_about.split(",")
for i as integer = 0 to ubound(flds)
if s > "" then s += " AND "
s += " dysfunctional_database_table." & flds(i) & "=current_database_table." & flds(i)
next
s = "SELECT * from dysfunctional_database_table where not exists (SELECT * from current_database_table WHERE " & s & ")"
====
我尝试使用 Linq 执行此操作,因为这似乎是两个不同数据库的一些数据类型问题类型变得不那么令人头痛, 但我是 Linq 的新手,完全陷入困境。
我得到了这样的结果:
将旧表和新表放入数据表中作为 dt1 和 dt2
Dim new_records = _ 来自 new_recs 中的 dt2.AsEnumerable 哪里不 (_ 来自 old_recs 在 dt1.AsEnumerable 其中 old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)).Any 选择新记录
但我不知道如何动态地将这部分放入 - old_recs(field1) = new_recs(field1) 还有 old_recs(field2) = new_recs(field2)
到目前为止我已经尝试过: 将我想要比较的字段放入字符串中,然后将该字符串作为变量放入(我以为我可能在作弊,我想我是)
dim str = old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)
From new_recs In dt2.AsEnumerable
Where Not ( _
From old_recs In dt1.AsEnumerable Where str).Any
Select new_recs
它告诉我它无法转换布尔值 -
有什么办法在没有 Linq 表达式的情况下执行此操作?它们看起来比我在这里尝试做的要复杂得多,并且需要大量代码,而且我似乎找不到我们在子查询中比较两个字段的表达式示例。
有没有更简单的方法?我知道我可以使用 JOIN 或 IN 执行通常的 EXISTS 查询 - 在这种情况下,我不需要查询超快或任何东西。我不需要使用 DataTable 或 DataSet - 我可以将数据放入其他类型的对象中。
I'm trying to query old Access database tables and compare them with SQL Server tables.
They often don't have primary keys, or they have extra fields that had some purpose in the nineties, etc., or the new tables have new fields, etc.
I need to find records - based on a set of fields specified at runtime - that are in one table but not another.
So, I do this kind of query all the time in SQL, when I'm comparing data in different tables:
dim fields_i_care_about as string = "field1, field2, field3"
'This kind of thing gets set by a caller, can be any number of fields, depends on the
'table
dim s as string= ""
dim flds = fields_i_care_about.split(",")
for i as integer = 0 to ubound(flds)
if s > "" then s += " AND "
s += " dysfunctional_database_table." & flds(i) & "=current_database_table." & flds(i)
next
s = "SELECT * from dysfunctional_database_table where not exists (SELECT * from current_database_table WHERE " & s & ")"
====
I'm trying to do this using Linq because it seems like some of the datatype problems with two different database types become less of a headache,
but I'm new to Linq and totally stuck.
I got as far as this:
Put old and new tables into datatables as dt1 and dt2
Dim new_records = _ From new_recs In dt2.AsEnumerable Where Not ( _ From old_recs In dt1.AsEnumerable Where old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)).Any Select new_recs
But I can't figure out how to put this part in on the fly -
old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)
So far I've tried:
putting the fields I want to compare and making them a string and just putting that string in as a variable ( I thought I was probably cheating, and I guess I was)
dim str = old_recs(field1) = new_recs(field1) AndAlso old_recs(field2) = new_recs(field2)
From new_recs In dt2.AsEnumerable
Where Not ( _
From old_recs In dt1.AsEnumerable Where str).Any
Select new_recs
It tells me it can't convert a Boolean -
Is there any way to do this without Linq expressions? They seem far more complex than what I'm trying to do here, and they take a lot of code, and also I can't seem to find examples of Expressions where we're comparing two fields in a subquery.
Is there a simpler way? I know I could do the usual EXISTS query using JOIN or IN - in this case I don't need the query to be super fast or anything. And I don't need to use a DataTable or DataSet - I can put the data in some other kind of object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以我找到了很多使用 MethodInfo 和反射之类的示例代码,但我无法让其中任何一个工作 - 这些 Datarows 有一个 Field 方法,但它要求您在之前添加一个(对象)参数字段名称参数,这很难做到。
所以我不确定这个解决方案是否是最有效的方法,但至少它有效。我有兴趣了解这种方法是否有效以及为什么或为什么不有效。似乎大多数人都使用反射来做这种事情,但我无法让它正常工作,无论如何我想做的事情非常简单,而这些方法非常复杂。我想我是用 SQL 思维方式做 Linq 的,但无论如何它是有效的。
So I found a lot of sample code that used MethodInfo and reflection and things like that, but I couldn't get any of it to work - these Datarows have a Field method but it requires that you add an (of object) argument before the field name argument and that's tricky to do.
So I'm not sure if this solution is the most efficient way, but at least it works. I'd be interested in finding out whether this way of doing it is efficient and why or why not. It seemed like most people used reflection to do this kind of thing, but I couldn't get that working properly and anyway what I'm trying to do is pretty simple while those methods were pretty complex. I suppose I'm doing Linq with a SQL mindset, but anyway it works.