Fluent Api - Mapping an index over more than one column across entity types.
See original GitHub issueI need to generate migration for my entity “Contact” has the “Complex Type -> Address”.
So far so good!
However, in the “Contact” entity I need to create a unique index containing “Complex Type -> Address” properties, which is causing migration error.
How can I create this unique index?
The code with example is in: https://github.com/lincolnzocateli/EFCoreExample/blob/master/Map/ContactMap.cs
using System.Linq;
using EfCoreExample.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace EfCoreExample.Map
{
public class ContactMap : IEntityTypeConfiguration<Contact>
{
public void Configure(EntityTypeBuilder<Contact> builder)
{
builder.ToTable("Contacts");
builder.HasKey(x => x.ContactId);
builder.Property(x => x.ContactId)
.IsRequired();
builder.Property(x => x.Name)
.IsRequired()
.HasColumnType("varchar(40)");
builder.Property(x => x.Observation)
.HasColumnType("varchar(100)");
builder.OwnsOne(x => x.Address).Property(x => x.AddressType)
.IsRequired()
.HasColumnType($"varchar(20)")
.HasColumnName("Type");
builder.OwnsOne(x => x.Address).Property(x => x.Street)
.IsRequired()
.HasColumnType($"varchar(60)")
.HasColumnName("Street");
builder.OwnsOne(x => x.Address).Property(x => x.Neighborhood)
.HasColumnType($"varchar(60)")
.HasColumnName("Complement");
builder.OwnsOne(x => x.Address).Property(x => x.City)
.IsRequired()
.HasColumnType($"varchar(60)")
.HasColumnName("City");
builder.OwnsOne(x => x.Address).Property(x => x.State)
.IsRequired()
.HasColumnType($"varchar(2)")
.HasColumnName("State");
builder.OwnsOne(x => x.Address).Property(x => x.Zip)
.IsRequired()
.HasColumnType($"varchar(8)")
.HasColumnName("ZipCode");
//(1:N)
builder.HasOne(x => x.Person)
.WithMany(c => c.Contacts)
.HasForeignKey(x => x.ContactId)
.OnDelete(DeleteBehavior.Restrict);
builder.HasIndex(e => new
{
e.Name,
e.Address.AddressType,
e.Address.Zip,
}).HasName("IX_MyIndex")
.IsUnique();
}
}
}
Exception message:
The properties expression 'e => new <>f__AnonymousType1`3(Name = e.Name, AddressType = e.Address.AddressType, Zip = e.Address.Zip)' is not valid. The expressionshould represent a property access: 't => t.MyProperty'. When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.
Parameter name: propertyAccessExpression
Stack trace:
System.ArgumentException: The properties expression 'e => new <>f__AnonymousType1`3(Name = e.Name, AddressType = e.Address.AddressType, Zip = e.Address.Zip)' isnot valid. The expression should represent a property access: 't => t.MyProperty'. When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.
Parameter name: propertyAccessExpression
at Microsoft.EntityFrameworkCore.Internal.ExpressionExtensions.GetPropertyAccessList(LambdaExpression propertyAccessExpression)
at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.HasIndex(Expression`1 indexExpression)
at EfCoreExample.Map.ContactMap.Configure(EntityTypeBuilder`1 builder) in /home/lincoln/Dropbox/EFCoreExample/Map/ContactMap.cs:line 70
at Microsoft.EntityFrameworkCore.ModelBuilder.ApplyConfiguration[TEntity](IEntityTypeConfiguration`1 configuration)
at EfCoreExample.Context.EfCoreExampleContext.OnModelCreating(ModelBuilder modelBuilder) in /home/lincoln/Dropbox/EFCoreExample/Context/EfExampleContext.cs:line 37
at Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__0(Object k)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_1(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.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_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
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.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Steps to reproduce
Generate migration for the first time: /> dotnet ef migrations add v1.0.0
Further technical details
EF Core version: Microsoft.EntityFrameworkCore.Design version 2.0.1 Microsoft.EntityFrameworkCore.Tools.DotNet version 2.0.1 Database Provider: Microsoft.EntityFrameworkCore.SqlServer version 2.0.1 Operating system: Linux Debian 9 IDE: VSCODE
Issue Analytics
- State:
- Created 6 years ago
- Reactions:134
- Comments:33 (11 by maintainers)
Top Results From Across the Web
Fluent API - Configuring and Mapping Properties and Types
Entity splitting uses multiple calls to the Map method to map a subset of properties to a specific table.
Read more >Unique Key constraints for multiple columns in Entity ...
With Entity Framework 6.1, you can now do this: [Index("IX_FirstAndSecond", 1, IsUnique = true)] public int FirstColumn { get; set; } ...
Read more >Configure Property Mappings using Fluent API in EF Code- ...
The Fluent API can be used to configure properties of an entity to map it with a db column. Using Fluent API, you...
Read more >Entity Framework - Fluent API
Entity mapping is just some simple mappings that will impact Entity Framework's understanding of how the classes are mapped to the databases. All...
Read more >The Fluent API HasIndex Method
The Entity Framework Core Fluent API HasIndex method is used to create a database index on the column mapped to the specified entity...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This issue is in the backlog milestone, which means we don’t plan to work on it for 5.0; once that’s released, we’ll reexamine which issues can make it into 6.0.
Note that this issue has an easy workaround - simply create the index in your migration - which means we generally don’t consider this to be extremely high priority.
We wanted to keep this open in the backlog.