Breeze / breeze.server.net

Breeze support for .NET servers
MIT License
76 stars 62 forks source link

Generation of metadata fails when an entity has two properties with the same owned type. #186

Closed apircher closed 1 year ago

apircher commented 1 year ago

I have an owned type called ChangeInfo:

[Owned]
public class ChangeInfo
{
    [MaxLength(256)]
    public required string By { get; set; }
    public DateTimeOffset At { get; set; }
}

And an entity which uses this type for creation and modification info:

public class MyEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    ...

    public required ChangeInfo Created { get; set; }

    public required ChangeInfo Modified { get; set; }

    ...
}

In Program.cs I try to create metadata for a DbContext which has a DbSet of this entity:

if (args.Length > 0 && args[0].Contains("metadata"))
{
    // Generate breeze metadata and exit.
    using (var serviceScope = app.Services.CreateScope())
    {
        var services = serviceScope.ServiceProvider;
        var context = services.GetRequiredService<MyDbContext>();
        var persistanceManager = new MyDbPersistenceManager(context);
        var metadata = persistanceManager.Metadata();
        Console.Out.WriteLine(metadata);
    }
    return;
}

But it fails with an ArgumentException which says "An item with the same key has already been added. Key: ChangeInfo".

The problem seems to occur in Breeze.Persistence.EFCore.MetadataBuilder in line 31.

I can reproduce the same exception with the following code:

using (var serviceScope = app.Services.CreateScope())
{
    var services = serviceScope.ServiceProvider;
    var context = services.GetRequiredService<MyDbContext>();

    var complexTypes = context.Model.GetEntityTypes()
        .Where(et => et.IsOwned())
        .Select(et => et.ClrType.Name).ToList();
    var map = complexTypes.ToDictionary(mt => mt);
}

This is quite similar to what happens in the MetadataBuilder from line 26 to 28. In this case the complexTypes list will contain two MetaType instances with a ShortName of 'ChangeInfo' and so the call complexTypes.ToDictionary(mt => mt.ShortName) throws the exception mentioned above.

I am using:

Any help would be greatly appreciated.

steveschmitt commented 1 year ago

Yes, it looks like a bug. We will get a fix in soon. Thanks for finding this and letting us know.

steveschmitt commented 1 year ago

Fixed in version 7.1.0