Рассмотрим эту простую модель:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace ConsoleApp3
{
public class ApplicationDbContext : DbContext
{
public DbSet<WTF> Wtf { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlServer("Server = (localdb)\\mssqllocaldb; Database=DAFAQ0001;Trusted_Connection=True;");
}
public class WTF
{
[DatabaseGenerated(DatabaseGeneratedOption.None), Key] public long Aargh { get; set; }
public override string ToString() => Aargh.ToString();
}
}
Давайте попробуем поместить одну строку в созданную таким образом таблицу и затем запросить эту единственную строку:
using System;
using System.Linq;
namespace ConsoleApp3
{
class Program
{
static void Main()
{
var db = new ApplicationDbContext();
db.Wtf.Add(new WTF { Aargh = 0 });
db.SaveChanges();
Console.WriteLine(db.Wtf.Any()); // TRUE
Console.WriteLine(db.Wtf.First().ToString()); // WORKS
Console.WriteLine(db.Wtf.Max(wtf => wtf.Aargh)); // EXCEPTION
}
}
}
Да - последняя Линия производит большое, толстое, безобразное исключение. Очевидно, sequence contains no elements
, что кажется странным, потому что он содержит один элемент, который я только что вставил! И сам метод Any
подтверждает это. Еще хуже - запрос этого единственного элемента также работает, что подтверждается вызовом First
. Это просто Max
, который терпит неудачу, по причинам, которые я не могу понять.
True
0
Unhandled exception. System.InvalidOperationException: Sequence contains no elements.
at lambda_method(Closure , QueryContext , DbDataReader , ResultContext , Int32[] , ResultCoordinator )
at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.Max[TSource,TResult](IQueryable`1 source, Expression`1 selector)
at ConsoleApp3.Program.Main() in C:\Users\m\source\repos\ConsoleApp3\ConsoleApp3\Program.cs:line 23
C:\Users\m\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp3.1\ConsoleApp3.exe (process 11432) exited with code -532462766.
Press any key to close this window . . .
Как ни странно, вставка этого единственного элемента с PK 1
вместо 0
, кажется, решает проблему.
Что здесь происходит? Является ли 0
недопустимым значением для первичного ключа? Я гуглил и нашел этот SO-ответ: SQL первичный ключ может принимать '0'? , что говорит о том, что 0
является совершенно допустимым значением первичного ключа!
Может кто-нибудь объяснить, почему не работает ли приведенный выше код?
Редактировать: Отвечать на комментарии: Если я щелкаю в VS окно SQL Server Explorer и вижу код этой таблицы, это то, что я получаю:
CREATE TABLE [dbo].[Wtf] (
[Aargh] BIGINT NOT NULL,
CONSTRAINT [PK_Wtf] PRIMARY KEY CLUSTERED ([Aargh] ASC)
);
Профилирование этого сценария в VS показывает, что SQL выполняется для получения Max
:
SELECT MAX([w].[Aargh]) FROM [Wtf] AS [w]
Выполнение этого же запроса SQL в Sql Обозреватель объектов сервера в VS создает следующие результаты:
(No column name)
0