dotnet / dotnet/efcore

Prevent mapping intrinsic types as complex types

Open
#32,695 4 comments 1 reaction 0 assignees View on GitHub
area-complex-types area-type-mapping customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

# Overview

Whilst messing around with complex types in an attempt to persist a `DateTimeOffset` as two separate columns (one containing the ticks, and another containing the offset ticks), I received an error telling me the following:

`System.ArgumentException: The specified type 'System.DateTimeOffset' must be a non-interface type with a public constructor to be used as a complex type.`

`DateTimeOffset` is not an interface type AND has a public constructor available to be used, so I assumed it was something else.

After delving into the `ComplexType` constructor, and subsequently the `SharedTypeExtensions.IsValidComplexType` extension method, I noticed that there is a check that identifies whether the provided type is a scalar type (which `DateTimeOffset` is). The thrown exception's message does not indicate this, and, although an unlikely occurrence, probably should?

# Repro steps

## Steps

1. Attempt to define a `DateTimeOffset` (or another scalar type) as a complex property on a model.
2. Migrate the database.
3. Boom.

## Code

```csharp
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

var serviceCollection = new ServiceCollection();
serviceCollection.AddDbContext(c => c.UseSqlite("Data Source=:memory:"));
var serviceProvider = serviceCollection.BuildServiceProvider();

var dbContext = serviceProvider.GetService();
dbContext.Database.Migrate();

public class Model
{
public DateTimeOffset Date { get; set; }
}

public class DatabaseContext : DbContext
{
public DbSet Models { get; set; }

public DatabaseContext(DbContextOptions options) : base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity()
.ComplexProperty(p => p.Date);
}
}
```

## System Information

EF Core version: 8.0.0
Database provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer) Microsoft.EntityFrameworkCore.Sqlite
Target framework: (e.g. .NET 6.0) .NET 8.0
Operating system: Windows 11
IDE: (e.g. Visual Studio 2022 17.4) Jetbrains Rider 2023.3

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.