Monthly Archives: July 2018

Short Walks – NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods

Not a huge post, but this has tripped me up several times, and sent me down some quite deep rabbit holes.

On to the story…

I once had a check to received calls like this:

var myData = Substitute.For<IData>();

. . .

myData
    .Add(Arg.Is<MyEntity>(a =>
        a.Active == true
        && a.Field1 == 1
        && a.Field2 == 42))
    .Received(1);

And I was getting the error:

NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods

I was confident that I had declared it correctly, a few lines above… I could, in fact see that I had declared it correctly. As my brain slowly dribbled from my nose, I did a quick search on the web; and found a solitary article that suggested I might have confused the Received and method calls; the correct syntax being:

myData
    .Received(1)
    .Add(Arg.Is<MyEntity>(a =>
        a.Active == true
        && a.Field1 == 1
        && a.Field2 == 42));

Hopefully, now that I’ve doubled the available resources available to people finding this error, it will plague me less in compensation.

Short Walks – System.InvalidOperationException: ‘The seed entity for entity type ‘MyEntity’ cannot be added because another seed entity with the same key value for {‘Id’} has already been added. Consider using ‘DbContextOptionsBuilder.EnableSensitiveDataLogging’ to see the conflicting key values.’

I got this error recently while playing with EF Core 2. There’s very little on Google about it; although it’s not a hugely difficult problem to solve, if I ever get it again, I can just Google it !

The error:

System.InvalidOperationException: ‘The seed entity for entity type ‘MyEntity’ cannot be added because another seed entity with the same key value for {‘Id’} has already been added. Consider using ‘DbContextOptionsBuilder.EnableSensitiveDataLogging’ to see the conflicting key values.’

If effectively cause by a conflict in the primary key; and it gives you the first step towards solving it in the error (in OnModelCreating):

var options =
    new DbContextOptionsBuilder<ApplicationDbContext>()
         .UseSqlServer(configuration.GetConnectionString("DefaultConnection"))
         .EnableSensitiveDataLogging()
         .Options;

Now it says:

System.InvalidOperationException: ‘The seed entity for entity type ‘MyEntity’ cannot be added because another seed entity with the key value ‘Id:1′ has already been added.’

In my particular case, I’d been playing around with adding some seed data, and had left this in (OnModelCreating):

modelBuilder.Entity<MyEntity>().HasData(new Data.MyEntity()
{
    Id = 1,
    Name = "Test",
    CreatedDate = new DateTime(2018, 07, 03),
    UpdatedDate = new DateTime(2018, 07, 03)
});

Short Walks – Data Seeding in Entity Framework Core 2

Entity Framework Core 2.1 has a nice little feature for seed data. Previously, seeding data quite often involved a series of checks and potential for a script to exist that, if run on the wrong data, would repeatedly re-generate the same seed data.

In 2.1, you can simply override the OnModelCreating function of the data context, like so:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
 
    public DbSet<ResourceType> ResourceType { get; set; }
 
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
 
        modelBuilder.Entity<ResourceType>().HasData(new Data.ResourceType()
        {
            Id = 1,
            Name = "Web Site"                
        });
    }

And the framework will calculate whether or not this needs to run to put the data into the state that you’ve requested.

References

https://docs.microsoft.com/en-us/ef/core/modeling/data-seeding

Short Walks – Setting up a Foreign Key Relationship in Entity Framework

Having had to search for this for the fiftieth time, I thought I’d document it here, so I knew where to look!

To set-up a foreign key relationship in EF, the first step is to define your classes; for example:

In this case, each Resource has a ResourceType in a simple one-to-many relationship. In the lookup table, in this case: ResourceType, define the key:

public class ResourceType
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    
}

(You’ll need to reference: System.ComponentModel.DataAnnotations)
Then, in the main table, in this case Resource, map a field to the Lookup, and then tell it how to store that in the DB:

public class Resource
{        
    public int Id { get; set; }
 
    public int ResourceTypeId { get; set; }
 
    [ForeignKey("ResourceTypeId")]
    public ResourceType ResourceType { get; set; } 
 
    public string Name { get; set; }
}

(You’ll need to reference: System.ComponentModel.DataAnnotations.Schema)

That’s it. Once you run Add-Migration, you should have a foreign key relationship set-up.