- По сути, я пытаюсь получить результат (здесь он называется Foo) с некоторыми деталями (здесь он называется Bar )
Детали не являются обязательными (например, может возникнуть ошибка) - Детали содержат множество вещей, в том числе другая сущность (здесь она называется Баз).
- не требуется, но при его установке также должен быть установлен Baz.
Код: Выделить всё
Bar
- Тип Baz используется, поскольку тип Baz используется повторно несколько раз.
- По крайней мере, это мое текущее понимание проблемы.
Вопрос: Почему это вызывает проблемы и как правильно указать это отношение?
Вопрос: есть ли какое-то обходное решение, чтобы это заработало?
Исключение
Код: Выделить всё
Unhandled exception. System.InvalidOperationException: An error occurred while reading a database value for property 'BazDto.BarDtoFooDtoId'. The expected type was 'System.Guid' but the actual value was null.
---> System.Data.SqlTypes.SqlNullValueException: Data is Null. This method or property cannot be called on Null values.
at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
at Microsoft.Data.SqlClient.SqlBuffer.get_Guid()
at Microsoft.Data.SqlClient.SqlDataReader.GetGuid(Int32 i)
at lambda_method32(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
--- End of inner exception stack trace ---
at lambda_method32(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
at Program.Main(String[] args) in D:\paul\CODE\playground\Playground_02\ConsoleApp1\Program.cs:line 88
at Program.Main(String[] args) in D:\paul\CODE\playground\Playground_02\ConsoleApp1\Program.cs:line 88
at Program.(String[] args)
Код: Выделить всё
// 1. Create a ConsoleApp project with .NET 8
// 2. Add The package references into the '.csproj'
// 3. Replace 'Program.cs' with this code
// 4. Update the ConnectionString to point to an SqlServer instance
// 5. Generate database migrations.
// 6. Run to reproduce the issue
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
public class FooDto
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public BarDto? Bar { get; set; }
}
[Owned]
public class BarDto
{
public BazDto Baz { get; set; } = null!;
// https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-6.0/breaking-changes#nested-optional-dependents-sharing-a-table-and-with-no-required-properties-are-disallowed
public int _RequiredFieldToAvoidWarning { get; set; }
}
[Owned]
public class BazDto
{
public int Id { get; set; }
}
public class ExampleContext : DbContext
{
public DbSet Foos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
base.OnConfiguring(options);
options.EnableDetailedErrors();
options.UseLoggerFactory(LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Trace);
}));
var connectionString = @"CONNECTION_STRING"; // UPDATE
options.UseSqlServer(connectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity(fooBuilder =>
{
fooBuilder.OwnsOne(x => x.Bar, barBuilder =>
{
barBuilder
.OwnsOne(x => x.Baz, bazBuilder =>
{
// This is required for the issue to occur, there needs to be a separate table
bazBuilder.ToTable("Baz");
});
});
});
}
}
internal class Program
{
public static async Task Main(string[] args)
{
await using var context = new ExampleContext();
await context.Database.MigrateAsync();
context.Foos.Add(new FooDto()
{
Id = Guid.NewGuid(),
Bar = null,
});
await context.SaveChangesAsync();
// This will throw an exception
var result = await context.Foos
.AsNoTracking()
.Include(x => x.Bar)
.ThenInclude(x => x!.Baz)
.FirstAsync();
}
}
Код: Выделить всё
all
runtime; build; native; contentfiles; analyzers; buildtransitive
- Migrations/ 20241016062147_Initial.cs
- Migrations/20241016062147_Initial.Designer.cs
- Migrations/ExampleContextModelSnapshot.cs
Изначально я пытался включить журналы в вопрос, но они превышают максимальный размер.
Журналы можно найти здесь.
Подробнее здесь: https://stackoverflow.com/questions/790 ... s-not-null