Mark Perry
Mark Perry

Reputation: 3626

EF AsNoTracking Causes error. Expression of type 'System.DateTime' cannot be used for assignment to type 'System.Nullable`1[System.DateTime]'

Today I decided to upgrade an old web project of mine from Asp.net core 1.1 to 2.1 and all was going quite smoothly until I attempted to retrieve a list of LocalEvent's from the DB. I was using .AsNotracking as I didn't need to make any changes to the objects beyond sorting / filtering.

This is the error:

Expression of type 'System.DateTime' cannot be used for assignment to type 'System.Nullable`1[System.DateTime]'

This is the code I am having issues with:

    var today = DateTime.Now;

    var events = await _context.LocalEvent.Where
    (x => x.ReoccurUntil > today || x.EventEnd > today).AsNoTracking().ToListAsync();

This is the LocalEvent model:

public class LocalEvent
{
    [NotMapped]
    private DateTime? dateCreated;

    [Key]
    public Guid Id { get; set; }

    [MaxLength(200)]
    [Display(Name = "Event Location")]
    [DataType(DataType.MultilineText)]
    public string Location { get; set; }

    [Display(Name = "Added By")]
    public string Author { get; set; }

    [Display(Name = "Contact")]
    public string EventContact { get; set; }

    [Display(Name = "Event Name")]
    public string EventName { get; set; }

    [DataType(DataType.MultilineText)]
    [Display(Name = "Details")]
    public string EventInfo { get; set; }

    [DataType(DataType.Currency)]
    [DisplayFormat(DataFormatString = "{0:C0}", ApplyFormatInEditMode = true)]
    [Display(Name = "Cost")]
    public Decimal? EventCost { get; set; }

    //DateStuff
    [Display(Name = "Date Created")]
    public DateTime DateCreated
    {
        get { return dateCreated ?? DateTime.Now; }
        set { dateCreated = value; }
    }

    [Display(Name = "Event Start")]
    public DateTime EventStart { get; set; }


    [DateGreaterThan("EventStart")]
    [Display(Name = "Event End")]
    public DateTime EventEnd { get; set; }

    public DateTime ReoccurUntil { get; set; }

    [Display(Name = "Reoccurrence Type")]
    public TypeOfOccurrence OccurrenceType { get; set; }

    [Display(Name = "Which Occurence of Weekday")]
    public Nth NthReOccurence { get; set; }

    [Display(Name = "Weekday for Reoccurence")]
    public DayOfWeek ReoccurrenceDay { get; set; }

    [Display(Name = "Occurrence Rate")]
    public OccurrenceRate Occurrence { get; set; }
    public bool DoesReoccur { get; set; }

    [DataType(DataType.ImageUrl)]
    public string Image { get; set; }

    public string ImageDeletePath { get; set; }
    public string Slug { get; set; }
}

For now I simply removed the AsNoTracking to get things working again. Am I doing something wrong?

The error is really weird because it mentions dates and so took a while to trace back to the AsNoTracking, I removed anything to do with dates, initially just removing nullable dates, then I realised a similar call for the admin list (a complete tracked list) worked with the only difference being AsNoTracking, and that's when (after testing) I decided to ask on here.

I was of the mind that if I have no intention of modifying, deleting etc I should avoid tracking to improve performance!?

Hopefully someone can shed a bit of light on the issue! Thanks in advance!

Upvotes: 3

Views: 706

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205589

It's caused by EF Core bug introduced in v2.1.

Reported and tracked by #12215: Exception when loading entity containing a primitive property with matching System.Nullable backing field.

No workaround provided, fix scheduled for v2.2.

What I can suggest is to force EF using the property rather than the backing field:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // ...

    modelBuilder.Entity<LocalEvent>()
        .Property(e => e.DateCreated)
        .UsePropertyAccessMode(PropertyAccessMode.Property);

    // ...
}

Upvotes: 3

Related Questions