Open andriysavin opened 6 years ago
@andriysavin The issue here is that owned types cannot be configured using a call the top level .Entity method. This was supposed to throw in 2.1, but that change was accidentally reverted-see issue #9148.
To make your code work you instead need to configure the property mapping for the owned type in each of the places it is used. For example:
modelBuilder.Entity<MyEntity>(cb =>
{
cb.OwnsOne(seg => seg.Owned1).Property(e => e.MyProperty);
cb.OwnsOne(seg => seg.Owned2).Property(e => e.MyProperty);
});
@ajcvickers Thanks for explaining, that makes it work, though this configuration may look messy if you have many properties in the owned type - you will have to repeat the same configuration:
cb.OwnsOne(seg => seg.Owned1, b =>
{
b.Property(e => e.MyProperty1);
b.Property(e => e.MyProperty2);
b.Property(e => e.MyProperty3);
b.Property(e => e.MyProperty4);
});
cb.OwnsOne(seg => seg.Owned2, b =>
{
b.Property(e => e.MyProperty1);
b.Property(e => e.MyProperty2);
b.Property(e => e.MyProperty3);
b.Property(e => e.MyProperty4);
});
cb.OwnsOne(seg => seg.Owned3, b =>
{
b.Property(e => e.MyProperty1);
b.Property(e => e.MyProperty2);
b.Property(e => e.MyProperty3);
b.Property(e => e.MyProperty4);
});
This can be simplified by extracting to a separate method or local function, of course, but looks not very fluent:
void buildAction(ReferenceOwnershipBuilder<MyEntity, OwnedEntity> b)
{
b.Property(e => e.MyProperty1);
b.Property(e => e.MyProperty2);
b.Property(e => e.MyProperty3);
b.Property(e => e.MyProperty4);
}
cb.OwnsOne(seg => seg.Owned1, buildAction);
cb.OwnsOne(seg => seg.Owned2, buildAction);
However, it's not all from me :) I want constructor injection in MyEntity as well, so I commented out the parameterless constructor (see code below). And now I'm getting:
System.InvalidOperationException: No suitable constructor found for entity type 'MyEntity'. The following parameters could not be bound to properties of the entity: 'owned1', 'owned2'.
I can guess that this is due to (from the docs):
EF Core cannot set navigation properties (such as Blog or Posts above) using a constructor.
What's the reason for this limitation for owned types? If I have nested owned types, does that mean that only innermost owned type will be able to use constructor injection?
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace TestEfCtorInjectionWithOwnedTypes
{
public class MyEntity
{
public int Id { get; set; }
public OwnedEntity Owned1 { get; private set; }
public OwnedEntity Owned2 { get; private set; }
//private MyEntity() { }
public MyEntity(OwnedEntity owned1, OwnedEntity owned2)
{
Owned1 = owned1;
Owned2 = owned2;
}
}
public class OwnedEntity
{
public double MyProperty { get; }
public OwnedEntity(double myProperty) => MyProperty = myProperty;
}
class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions options) : base(options) { }
public DbSet<MyEntity> MyEntities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>(cb =>
{
cb.OwnsOne(seg => seg.Owned1).Property(e => e.MyProperty);
cb.OwnsOne(seg => seg.Owned2).Property(e => e.MyProperty);
});
}
}
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddDbContext<MyDbContext>(options =>
options.UseInMemoryDatabase("MyDatabase"));
using (var sp = services.BuildServiceProvider())
{
var dbContext = sp.GetRequiredService<MyDbContext>();
dbContext.MyEntities.Add(
new MyEntity(
new OwnedEntity(42),
new OwnedEntity(24)));
}
}
}
}
Here is an example with nested entities which doesn't work as well with error
System.InvalidOperationException: No suitable constructor found for entity type 'OwnedEntity'. The following parameters could not be bound to properties of the entity: 'ownedOwnedProperty'.
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace TestEfCtorInjectionWithOwnedTypes
{
public class MyEntity
{
public int Id { get; set; }
public OwnedEntity Owned { get; private set; }
private MyEntity() { }
public MyEntity(OwnedEntity owned) => Owned = owned;
}
public class OwnedEntity
{
public OwnedOwnedEntity OwnedOwnedProperty { get; }
public OwnedEntity(OwnedOwnedEntity ownedOwnedProperty)
=> OwnedOwnedProperty = ownedOwnedProperty;
}
public class OwnedOwnedEntity
{
public double MyProperty { get; }
public OwnedOwnedEntity(double myProperty) => MyProperty = myProperty;
}
class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions options) : base(options) { }
public DbSet<MyEntity> MyEntities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>(cb =>
{
cb.OwnsOne(seg => seg.Owned, b =>
{
b.OwnsOne(e => e.OwnedOwnedProperty).Property(e => e.MyProperty);
});
});
}
}
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection();
services.AddDbContext<MyDbContext>(options =>
options.UseInMemoryDatabase("MyDatabase"));
using (var sp = services.BuildServiceProvider())
{
var dbContext = sp.GetRequiredService<MyDbContext>();
dbContext.MyEntities.Add(
new MyEntity(new OwnedEntity(new OwnedOwnedEntity(4242))));
}
}
}
}
Re-opening to discuss in triage.
Triage: moving this to the backlog as a feature request to pass related entity instances to the constructor of a parent instance, which is most useful for aggregates. See also #1985
Just to give a more real life example, here are some of my models (simplified). To be accurate, this is how I want them to look like: GeoPosition and GeoSegment being value objects (immutable) and use constructor injection for instance creation, no default ctor (even private), no private setters, and are Owned Types.
public sealed class GeoPosition
{
public double Latitude { get; }
public double Longitude { get; }
public GeoPosition(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
}
public sealed class GeoSegment
{
public GeoPosition Start { get; }
public GeoPosition End { get; }
public GeoSegment(GeoPosition start, GeoPosition end)
{
Start = start;
End = end;
}
}
public class MyEntity
{
public int Id { get; set; }
public GeoSegment Location { get; set; }
public MyEntity(GeoSegment location)
{
Location = location;
}
}
The same model example can be considered for issue #12118
Any update or alternative solution for this?
@bicatu What is the specific problem for which are you looking for an alternative solution?
This issue is in the Backlog milestone. This means that it is not going to happen for the 3.0 release. We will re-assess the backlog following the 3.0 release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.
I have an aggregateRoot (A) that has a constructor that receives some Value Objects and an entity (B) that is part of the aggregate.
imagine
a = new A(VO, VO, new B())
@bicatu The only alternative solution that EF currently supports is to create a constructor that doesn't take B
and then allow EF to set B
after creation. The setter for B
can be private.
I ran into the same issue even without using related entities. Found a solution for my case. Hope this will help you guys.
Quick example:
public class Event {
public Event(string subject, DateTime startDate, DateTime endDate, bool enablePrivate)
{
Subject = subject;
StartDate = startDate;
PrivateEvent = enablePrivate;
EndDate = endDate;
}
public string Subject { get; private set; }
public DateTime StartDate { get; private set; }
public DateTime EndDate { get; private set; }
public bool PrivateEvent { get; private set; }
}
This gave me the following exception: System.InvalidOperationException : No suitable constructor found for entity type 'Event'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'enablePrivate'
So what I have found in the Microsoft docs (https://docs.microsoft.com/de-de/ef/core/modeling/constructors) : "The parameter types and names must match property types and names, except that properties can be Pascal-cased while the parameters are camel-cased."
In that case the solution was to rename the parameter to "enablePrivate" and the exception was gone.
Adding support for navigation-property via constructor is essential to accommodating C# 8.0's new nullable reference mode.
modelBuilder.Entity<Workstation>()
.HasOne(w => w.Owner)
.WithMany()
.HasForeignKey("OwnerId");
class Workstation
{
public User Owner { get; set; } // CS8618 Non-nullable property 'Owner' is uninitialized.
public string Hostname { get; set; }
}
class Workstation
{
public User Owner { get; set; }
public string Hostname { get; set; }
public Workstation(User owner, string hostname)
{
Owner = owner;
Hostname = hostname;
}
}
// Exception: No suitable constructor found for entity type 'Workstation'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'owner' in 'Workstation(User owner, string hostname)'
Adding support for navigation-property via constructor is essential to accommodating C# 8.0's new nullable reference mode.
@M-Pixel There is a doc page which describes how to work with NRTs in EF Core (and fix the warning): https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types
Having exactly the issue mentioned in the sample by @andriysavin above in a real world application.
We have a nested LatLngPoint
in the LatLngBounds
object. Both are value objects used as owned types in an aggregated root.
public sealed class LatLngPoint : ValueObject<LatLngPoint>
{
private LatLngPoint(double latitude, double longitude)
{
// Argument validation...
this.Latitude = latitude;
this.Longitude = longitude;
}
public double Latitude { get; }
public double Longitude { get; }
}
public sealed class LatLngBounds : ValueObject<LatLngBounds>
{
private LatLngBounds(LatLngPoint southwest, LatLngPoint northeast)
{
this.Southwest = southwest ?? throw new ArgumentNullException(nameof(southwest), "...");
this.Northeast = northeast ?? throw new ArgumentNullException(nameof(northeast), "...");
}
public LatLngPoint Southwest { get; }
public LatLngPoint Northeast { get; }
}
public class Map : IShadowUserAuditableEntity, IAggregateRoot
{
private Map(Guid id)
{
// Argument validation...
this.Id = id;
}
public Guid Id { get; }
public LatLngBounds Viewport { get; }
}
public class MapEntityTypeConfiguration : IEntityTypeConfiguration<Map>
{
public void Configure(EntityTypeBuilder<Map> builder)
{
...
builder.OwnsOne(e => e.Viewport, builder =>
{
builder.OwnsOne(e => e.Southwest, builder =>
{
builder.Property(e => e.Latitude)
.IsRequired()
.HasColumnName("SouthwestLat");
builder.Property(e => e.Longitude)
.IsRequired()
.HasColumnName("SouthwestLng");
});
builder.OwnsOne(e => e.Northeast, builder =>
{
builder.Property(e => e.Latitude)
.IsRequired()
.HasColumnName("NortheastLat");
builder.Property(e => e.Longitude)
.IsRequired()
.HasColumnName("NortheastLng");
});
});
...
}
}
Results in:
System.InvalidOperationException: No suitable constructor found for entity type 'LatLngBounds'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'southwest', 'northeast' in 'LatLngBounds(LatLngPoint southwest, LatLngPoint northeast)'.
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext`1 context)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_Model()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Include[TEntity,TProperty](IQueryable`1 source, Expression`1 navigationPropertyPath)
Further adding LatLngBounds
as a parameter to the Map
aggregate root constructor results in:
System.InvalidOperationException: No suitable constructor found for entity type 'Map'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'viewport', 'mode' in 'Map(Guid id, LatLngBounds viewport, Nullable<MapMode> mode)'; cannot bind 'viewport' in 'Map(Guid id, LatLngBounds viewport, MapMode mode)'.
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext`1 context)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_Model()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Include[TEntity,TProperty](IQueryable`1 source, Expression`1 navigationPropertyPath)
Yeah I appear to be having the same issue as well. Not sure if this is thought to be resolved? I may be doing something wrong.
This remains an issue in 5.x
This would be a really useful feature, especially for required one-to-to or many-to-one related entities. Without this feature one could not really validate, whether the entity constructed by EF actually has the required related entity property really set (nullability might be violated)!
My issue about this was indeed a duplicate. Updated my sample to support migration generation with an empty constructor but still using private setters for the properties. Now only the default constructor gives the NRT warning but nearly there.
3 years and 7 months later, this remains an issue in v6.0.1.
I'm using the #nullable setting in projects and now I have to do this: private Entity() { OwnedProperty = default!; }
.
Instead of the expected: private Entity(OwnedProperty ownedProperty) { OwnedProperty = ownedProperty; }
.
@ErroneousFatality As in all software development, we have limited resources and have to make hard decisions about what to prioritize. Make sure to vote (👍) for this issue if it is important to you. It currently has 18 votes, which puts it in 78th place in the list of top voted issues.
See The Planning Process for more information on how we decide what to work on.
I am trying to have an explicit many-to-many association (because implicit many-to-many associations create unwanted shadow properties):
[Owned]
class PersonWorkplace {
Person RefPerson { get; } Workplace RefWorkplace { get; }
public PersonWorkpace (Person refPerson, Workplace refWorkplace) { … }}
It feels like basic stuff (like WMI-style associations) does not work :disappointed:
System.InvalidOperationException: No suitable constructor was found for entity type 'MedicWorkplace'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'refMedic', 'refWorkplace' in 'MedicWorkplace(Medic refMedic, Workplace refWorkplace)'.
at Microsoft.EntityFrameworkCore.Metadata.Internal.ConstructorBindingFactory.GetBindings(IReadOnlyEntityType entityType, Func`5 bind, InstantiationBinding& constructorBinding, InstantiationBinding& serviceOnlyBinding)
at Microsoft.EntityFrameworkCore.Metadata.Internal.ConstructorBindingFactory.GetBindings(IMutableEntityType entityType, InstantiationBinding& constructorBinding, InstantiationBinding& serviceOnlyBinding)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext`1 context)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalizing(IConventionModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalizing(IConventionModelBuilder modelBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
at Microsoft.EntityFrameworkCore.Infrastructure.ModelRuntimeInitializer.Initialize(IModel model, Boolean designTime, IDiagnosticsLogger`1 validationLogger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, ModelCreationDependencies modelCreationDependencies, Boolean designTime)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(Boolean designTime)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__8_4(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_ContextServices()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at Microsoft.EntityFrameworkCore.Design.DbContextActivator.CreateInstance(Type contextType, Assembly startupAssembly, IOperationReportHandler reportHandler, String[] args)
at Microsoft.EntityFrameworkCore.Design.DbContextActivator.CreateInstance(Type contextType, Assembly startupAssembly, IOperationReportHandler reportHandler)
at Microsoft.VisualStudio.Web.CodeGeneration.EntityFrameworkCore.EntityFrameworkModelProcessor.TryCreateContextUsingAppCode(Type dbContextType, Type startupType) in /home/dell/prog/Scaffolding/src/Scaffolding/VS.Web.CG.EFCore/EntityFrameworkModelProcessor.cs:line 685
3 years and 7 months later, this remains an issue in v6.0.1. I'm using the #nullable setting in projects and now I have to do this:
private Entity() { OwnedProperty = default!; }
. Instead of the expected:private Entity(OwnedProperty ownedProperty) { OwnedProperty = ownedProperty; }
.
I would even say
[Obsolete ("see <URL: https://github.com/dotnet/efcore/issues/12078 >")]
private Entity() { OwnedProperty = default!; }
Any updates on this? Would be really useful!
This issue is in the Backlog milestone. This means that it is not planned for the next release (EF Core 8.0). We will re-assess the backlog following the this release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources. Make sure to vote (👍) for this issue if it is important to you.
Note--see comments for actual issue.
Original issue: I'm trying constructor injection feature of EF Core 2.1 RC1. Consider the following entities and DBContext configuration:
When I'm trying to add a new entity to the set, I'm getting the following exception:
What is interesting is that if I remove Owned1 or Owned2 property and all references to it, all works fine, though they are identical from configuration point of view. So its essential for this issue that at least two owned properties are present.
Further technical details
EF Core version: 2.1.0-rc1-final Database Provider: doesn't matter, but is reproducable with InMemory and SqlServer. IDE: Visual Studio 2017 15.7
Link to the VS solution on OneDrive: https://1drv.ms/u/s!AuaAKPMkiTEAxqgGlJX81J_GvbwIGA