Я пытаюсь выяснить разницу между следующим:
someListOfEnums.Cast<int>()
и
someListOfEnums.Select(a => (int)a)?
Я обнаружил, что первое вызывает исключение при использовании в Where
пункт в Entity Framework Core 3.1, но последний не делает. Я бы ожидал, что они будут действовать аналогично.
Возьмите следующий пример: publi c enum Fruit {Apple, Banana, Orange}
public class FruitTable
{
public int Id { get; set; }
public Fruit Value { get; set; }
}
public class FruitContext : DbContext
{
public DbSet<FruitTable> Fruit { get; set; }
}
public void TestMethod(FruitContext context)
{
var list = new List<Fruit>{Fruit.Apple, Fruit.Orange};
var breaks = list.Cast<int>();
var works = list.Select(a => (int)a);
var fruits1 = context.Fruit.Where(a => works.Contains(a.Value)).ToList(); //This works
var fruits2 = context.Fruit.Where(a => breaks.Contains(a.Value)).ToList(); //This breaks
}
Кажется например, использование .Cast<int>()
приводит к предложению where, содержащему имя перечисления (Apple, Orange и т. д. c.), тогда как использование .Select(a => (int)a)
- нет.
UPDATE
Я понял, что мой пример выше не вызывает той же проблемы (извинения). Я прошел и создал программу, которая определенно воспроизводит проблему.
Используя следующую базу данных:
CREATE DATABASE Fruit
USE Fruit
CREATE TABLE Fruit
(
Id INT NOT NULL PRIMARY KEY,
Value INT NOT NULL,
)
INSERT INTO Fruit VALUES (1, 0)
INSERT INTO Fruit VALUES (3, 2)
Следующая программа:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace ConsoleApp
{
public class Program
{
static void Main(string[] args)
{
FruitTable.TestMethod(new FruitContext());
}
public enum Fruit
{
Apple,
Banana,
Orange
}
public class FruitTable
{
public int Id { get; set; }
public int Value { get; set; }
public static void TestMethod(FruitContext context)
{
IEnumerable<Fruit> list = new Fruit[] {Fruit.Apple, Fruit.Orange};
var breaks = list.Cast<int>();
var works = list.Select(a => (int) a);
var fruits1 = context.Fruit.Where(a => works.Contains(a.Value)).ToList(); //This works
var fruits2 = context.Fruit.Where(a => breaks.Contains(a.Value)).ToList(); //This breaks
}
}
public class FruitContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=.;Database=fruit;Trusted_Connection=True;ConnectRetryCount=0");
}
public DbSet<FruitTable> Fruit { get; set; }
}
}
}
Вызывает следующая ошибка:
'Неверное имя столбца' Orange '. Неверное имя столбца 'Apple'. '
Редактировать
Просто добавить проблему не было в. Net Core 2.2, это появился, когда мы перешли на 3.1. Думая об этом - это может быть из-за этого: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#linq -queries-are-no-больше не оценивается-на-клиенте