简体   繁体   中英

Inverse navigation shadow properties and proxies

I'm encountering problems with EF Core 5.0 when I try to map a many-to-many relationship with a CLR navigation property on one end of the relationship only.

For example, a Question can have many Answers, and a single Answer can apply to many Questions (duplicates). To keep things simple, I don't want to navigate back from an answer to the duplicate questions.

public class Question
{
    public int Id { get; set; }

    public virtual IEnumerable<Answer> Answers { get; set; } = new List<Answer>();

    public string Text { get; set; } = "";
}

public class Answer
{
    public int Id { get; set; }

    public string Text { get; set; } = "";
}

public class SomeDbContext : DbContext
{
    public DbSet<Question> Questions => Set<Question>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Question>().HasMany(q => q.Answers).WithMany("Duplicates");
    }
}

This works fine, until I enable change tracking proxies or lazy-loading proxies. Then I start getting exceptions that say I need to add an inverse navigation property.

System.InvalidOperationException: Property 'Duplicates' on entity type 'Answer' is mapped without a CLR property. 'UseChangeTrackingProxies' requires all entity types to be public, unsealed, have virtual properties, and have a public or protected constructor. 'UseLazyLoadingProxies' requires only the navigation properties be virtual.

I understand that proxies require virtual navigation properties in order to add the desired behavior, but is there no way to do this with shadow properties?

I understand that proxies require virtual navigation properties in order to add the desired behavior, but is there no way to do this with shadow properties?

Currently (up to v6.0 inclusive) EF Core does not support shadow navigation properties.

I'm encountering problems with EF Core 5.0 when I try to map a many-to-many relationship with a CLR navigation property on one end of the relationship only.

As explicitly stated at the beginning of the Many-to-many documentation:

Many-to-many relationships require a collection navigation property on both sides.

There are plans to add support for single side skip navigation (unidirectional) many-to-many relationships in the future, but currently this is a limitation (and requirement for your model).

This works fine, until I enable change tracking proxies or lazy-loading proxies.

As mentioned above, what you are doing is not supported. You just found a backdoor in 5.0 which btw is closed in 6.0, so in 6.0 such model configuration simply throws InvalidOperationException saying

Unable to set up a many-to-many relationship between 'Answer.Duplicates' and 'Question.Answers' because one or both of the navigations don't have a corresponding CLR property. Consider adding a corresponding private property to the entity CLR type.

even without tracking or lazy loading proxies.

Shortly, whether you want it or not, the proper way until they add support for what you are asking for is to simply follow their requirements and put collection navigation properties on both sides.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM