Sql server 使用contains匹配两个字段
我有一个数据库表,它有一组字段,其中一个名为Sql server 使用contains匹配两个字段,sql-server,linq,Sql Server,Linq,我有一个数据库表,它有一组字段,其中一个名为Type,另一个名为code。我还有一个类中封装的Type和code对的列表。大概是这样的: public class TypeAndCode { public byte Type { get; set; } public int Code { get; set; } // overrides for Equals and GetHashCode to compare if Type and Code are equal }
Type
,另一个名为code
。我还有一个类中封装的Type
和code
对的列表。大概是这样的:
public class TypeAndCode
{
public byte Type { get; set; }
public int Code { get; set; }
// overrides for Equals and GetHashCode to compare if Type and Code are equal
}
var query = myTable.Where(a => myTCList.Contains(new TypeAndCode() { Type = a.Type, Code = a.Code }).ToList();
现在我需要做的是从表中只选择那些类型和代码与我的集合中的条目匹配的条目。例如,我试过这样的方法:
public class TypeAndCode
{
public byte Type { get; set; }
public int Code { get; set; }
// overrides for Equals and GetHashCode to compare if Type and Code are equal
}
var query = myTable.Where(a => myTCList.Contains(new TypeAndCode() { Type = a.Type, Code = a.Code }).ToList();
但这会给我一个不受支持的例外:
Unable to create a constant value of type 'TypeAndCode'. Only primitive types
or enumeration types are supported in this context.
是否有一种方法可以使此工作正常,以便我可以从数据库中仅检索那些具有与我的code
和Type
列表相匹配的code
和Type
的条目?我试图避免检索所有条目(这是一个大表)并在内存中匹配它们
我知道我可以试试这样的东西
var query = myTable.Where(a => listOfTypes.Contains(a.Type) && listOfCodes.Contains(a.Codes))
但如果类型和代码来自我原始列表中的不同对,则会产生一些虚假匹配。您可以使用
任何
:
var query = myTable
.Where(a => myTCList.Any(t => t.Type == a.Type && t.Code == a.Code ))
.ToList();
您应该能够手动执行此操作,而无需类中的重载方法:
myTCList.Any(x => x.Type == a.Type && x.Code == a.Code)
在这里,我的ulitmate解决方案(以防其他人遇到类似问题)是建立一个临时表,我可以编写我想要匹配的对,我可以将它们与数据库表连接起来。执行联接并具体化结果后,可以删除临时表 比如:
ctx.myTempTable = (from pair in mypairs
select new myTempTable() { Type = pair.Type, Code = pair.Code }).ToList();
ctx.SaveChanges();
var query = from q in myTable
join t in ctx.myTempTable
on new { q.Type, q.Code } equals new { t.Code, t.Type }
select q;
整个过程是在一个
try
/catch
/finally
块中,使用finally
块来清除临时表实际上,这是我最初尝试的,但我得到的是相同的NotSupportedException
。您使用的是什么Linq提供程序?它似乎无法将其转换为sql,因为它是一个具有多个属性的复杂对象。如果表不大,可以先添加一个numerable将所有内容读入内存。那么您的包含检查也应该可以工作,因为您已经重写了Equals。我正在从sql server中的一个大表中提取,所以我真的想尝试找到一种方法,尽可能避免提取所有内容。将其转换为sql的问题是可以理解的,我想看看是否有解决办法。看起来我能期望的最好的方法就是确保这是最后一个过滤器,这样我就可以在内存中应用它之前尽可能地减少列表。@MattBurland:我不知道还有比你已经遇到的更好的方法(“我知道我可以尝试…”)。但是,为什么需要按本地集合进行筛选?其思想是用户将选择一组代码/类型对,我需要从表中检索与其中一个代码/类型对匹配的所有条目。也许是走错了路?也许我需要写一个临时表,这样我就可以加入它了?难道Any
不返回bool
而不是匹配项的列表吗?()@JeffBridgman的确,与即将被替换的Contains完全相同。+1我不是数据库驱动LINQ提供程序方面的专家,但显然这无法转换为sql。问题是,本地集合只能与Contains
一起使用,并且只能在它只包含int
、DateTime
或string
等基本类型时使用。您的类包含两个属性,LINQ不知道该做什么。您可以使用.Where(a=>myTCList.Select(tc=>tc.Type).Contains(a.Type)和&myTCList.Select(tc=>tc.code).Contains(a.code))
。但这会有点低效。如前所述,你也知道这一点。