说我有以下SQL Server表:
CREATE TABLE ExampleTable (
A INT NOT NULL,
B INT NOT NULL,
C INT NOT NULL,
CONSTRAINT PK_A PRIMARY KEY CLUSTERED(A),
CONSTRAINT UK_BC UNIQUE(B,C)
);
INSERT INTO ExampleTable VALUES (1, 0, 0);
INSERT INTO ExampleTable VALUES (2, 0, 1);
INSERT INTO ExampleTable VALUES (3, 1, 0);
INSERT INTO ExampleTable VALUES (4, 1, 1);
假设我知道条目的B和C值,我需要学习A值。我显然可以编写以下T-SQL查询:
SELECT * FROM [dbo].[ExampleTable] WHERE (B = 0 AND C = 0) -- Returns (1,0,0)
但是,我希望以这种方式查找大量条目的图像,我希望将此查找作为单个数据库查询的一部分完成。我可以看到以下T-SQL查询:
SELECT * FROM [dbo].[ExampleTable] WHERE (B = 0 AND C = 0) OR (B = 1 AND C = 1) -- OR (Additional entity... Returns (1,0,0), (4,1,1), etc.
或者,我可以创建一个存储过程,在多列上进行连接:
CREATE TYPE BCPairsType AS TABLE (B INT, C INT);
CREATE PROCEDURE GetFromBAndC
@BCPairs BCPairsType READONLY
AS
SELECT ExampleTable.A, ExampleTable.B, ExampleTable.C
FROM ExampleTable
JOIN @BCPairs bcPairs ON
ExampleTable.B = bcPairs.B AND
ExampleTable.C = bcPairs.C
GO
DECLARE @input AS BCPairsType;
INSERT INTO @input VALUES (0,0);
INSERT INTO @input VALUES (1,1);
-- Add entries as necessary
EXEC GetFromBAndC @input -- Returns (1,0,0), (4,1,1), etc.
但是,现在我希望以一种不涉及编写和维护存储过程的方式在Entity Framework(v6.1.3)中解决这个问题。以下是我最终的逻辑:
EF模型+ POCO:
public partial class ExampleModel : DbContext
{
public ExampleModel()
: base("name=ExampleModel")
{
}
public virtual DbSet<ExampleTable> ExampleTables { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
[Table("ExampleTable")]
public partial class ExampleTable
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
}
模仿策略的逻辑#1:
var model = new ExampleModel();
var pairsToLookup = new List<Tuple<int,int>>
{
new Tuple<int, int>(0,0),
new Tuple<int, int>(1,1)
};
var results =
model.ExampleTables.Where(row => pairsToLookup.Contains(new Tuple<int, int>(row.B, row.C))).ToList();
模仿策略#2的逻辑:
var model = new ExampleModel();
var pairsToLookup = new List<Tuple<int, int>>
{
new Tuple<int, int>(0,0),
new Tuple<int, int>(1,1)
};
var q = from exampleTableValue in model.ExampleTables.AsQueryable()
join inputTuple in pairsToLookup.AsQueryable()
on new {b = exampleTableValue.B, c = exampleTableValue.C } equals new { b = inputTuple.Item1, c = inputTuple.Item2 }
select exampleTableValue;
var results = q.ToList();
然而,这两种策略都不起作用,我留下了以下错误:
System.NotSupportedException:无法创建类型&#39; System.Tuple`2 [[System.Int32,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089],[System。 Int32,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]&#39;。在此上下文中仅支持原始类型或枚举类型。
根据我所能提到的其他问题,由于实体框架将任意.NET代码转换为T-SQL的能力有限,因此引发此错误。 (EF声称它只支持原始类型或枚举类型。)但是,我无法看到任何明显的方法,我可以在任一策略中重写逻辑以使用原始类型,同时支持配对已知B和C值的概念。有没有人知道我可以让EF执行这个逻辑而不需要使用存储过程?