AnswerBun.com

EF Core multiple navigation properties to same table with fluent api

Stack Overflow Asked by TheMuyu on July 23, 2020

I searched a lot but no luck to find a solution to my entities.

I have 2 entities. Device & PersonEnterExit
I have 2 Collection of PersonEnterExit in Device entity.
When I run database update it says me you have same entity with different name. do manually name them. how do i do that ? I want to do this with fluent api in onModelCreating.

Devices.cs

using System;
using System.Collections.Generic;

namespace DesTech.Core.Entities
{
    public class Device : BaseEntity
    {
        public bool? IsConnected { get; set; }
        public string Name { get; set; }
        public string Ip { get; set; }
        public int Port { get; set; }
        public DateTime? LastConnectTime { get; set; }
        public DateTime? ChangeClockBatteryWarningTime { get; set; }
        public bool HasFp { get; set; }

        public virtual Location Location { get; set; }
        public virtual ICollection<DeviceOptLog> DeviceOptLog { get; set; }
        public virtual ICollection<DevicePerson> DevicePerson { get; set; }
        public virtual ICollection<DeviceTimeZone> DeviceTimeZone { get; set; }
        public virtual ICollection<PersonEnterExit> PersonEnterExitEnDevice { get; set; }
        public virtual ICollection<PersonEnterExit> PersonEnterExitExDevice { get; set; }
        public virtual ICollection<PersonPassLog> PersonPassLog { get; set; }
    }
}

PersonEnterExit.cs

using System;

namespace DesTech.Core.Entities
{
    public class PersonEnterExit : BaseEntity
    {
        public int Type { get; set; }
        public int? PersonId { get; set; }
        public DateTime? NoEnterTime { get; set; }
        public int? EnDeviceId { get; set; }
        public DateTime? EnVerifyDate { get; set; }
        public string EnPlate { get; set; }
        public int? ExDeviceId { get; set; }
        public DateTime? ExVerifyDate { get; set; }

        public virtual Device EnDevice { get; set; }
        public virtual Device ExDevice { get; set; }
        public virtual Person Person { get; set; }

    }
}

3 Answers

You can use one of these

  1. FluentApi
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Device>()
        .HasMany(a => a.PersonEnterExitEnDevice)
        .WithOne(a => a.EnDevice)
        .HasForeignKey(a => a.EnDeviceId).OnDelete(DeleteBehavior.Restrict); 

    modelBuilder.Entity<Device>()
        .HasMany(a => a.PersonEnterExitExDevice)
        .WithOne(a => a.ExDevice)
        .HasForeignKey(a => a.ExDeviceId).OnDelete(DeleteBehavior.Restrict); 
}
  1. Metadata. you can use InverseProperty to define the relationships.
namespace DesTech.Core.Entities
{
    public class PersonEnterExit : BaseEntity
    {
        public int Type { get; set; }
        public int? PersonId { get; set; }
        public DateTime? NoEnterTime { get; set; }
        public int? EnDeviceId { get; set; }
        public DateTime? EnVerifyDate { get; set; }
        public string EnPlate { get; set; }
        public int? ExDeviceId { get; set; }
        public DateTime? ExVerifyDate { get; set; }
        [InverseProperty("PersonEnterExitEnDevice")]
        public virtual Device EnDevice { get; set; }
        [InverseProperty("PersonEnterExitExDevice")]
        public virtual Device ExDevice { get; set; }
        public virtual Person Person { get; set; }

    }
}
namespace DesTech.Core.Entities
{
    public class Device : BaseEntity
    {
        public bool? IsConnected { get; set; }
        public string Name { get; set; }
        public string Ip { get; set; }
        public int Port { get; set; }
        public DateTime? LastConnectTime { get; set; }
        public DateTime? ChangeClockBatteryWarningTime { get; set; }
        public bool HasFp { get; set; }

        public virtual Location Location { get; set; }
        public virtual ICollection<DeviceOptLog> DeviceOptLog { get; set; }
        public virtual ICollection<DevicePerson> DevicePerson { get; set; }
        public virtual ICollection<DeviceTimeZone> DeviceTimeZone { get; set; }
        [InverseProperty("EnDevice")]
        public virtual ICollection<PersonEnterExit> PersonEnterExitEnDevice { get; set; }
        [InverseProperty("ExDevice")]
        public virtual ICollection<PersonEnterExit> PersonEnterExitExDevice { get; set; }
        public virtual ICollection<PersonPassLog> PersonPassLog { get; set; }
    }
}

Correct answer by Farhad Zamani on July 23, 2020

Okey I combined two answers and its works now. I reply my question for maybe others use same approach. If i mistake please warn me. But it works now.

        builder.HasMany(a => a.PersonEnterExitEnDevice)
            .WithOne(a => a.EnDevice)
            .HasForeignKey(a => a.EnDeviceId)
            .OnDelete(DeleteBehavior.Restrict); 

        builder.HasMany(a => a.PersonEnterExitExDevice)
            .WithOne(a => a.ExDevice)
            .HasForeignKey(a => a.ExDeviceId)
            .OnDelete(DeleteBehavior.Restrict); 


        builder.HasOne(d => d.EnDevice)
            .WithMany(e => e.PersonEnterExitEnDevice)
            .HasForeignKey(d => d.EnDeviceId)
            .HasConstraintName("FK_PersonEnterExit_DeviceEn");

        builder.HasOne(d => d.EnLocation)
            .WithMany(e => e.PersonEnterExitEnLocation)
            .HasForeignKey(d => d.EnLocationId)
            .HasConstraintName("FK_PersonEnterExit_LocationEx");

Answered by TheMuyu on July 23, 2020

Like you mentioned, you need to explicitly configure both relationships. Otherwise, EF will get confused.

build.Entity<PersonEnterExit>()
     .HasOne(e => e.EnDevice)
     .WithMany(d => d.PersonEnterExitEnDevice);

build.Entity<PersonEnterExit>()
     .HasOne(e => e.ExDevice)
     .WithMany(d => d.PersonEnterExitExDevice);

See if this helps. You may need to explicitly configure foreign keys if this doesn't work.

Answered by Tanveer Badar on July 23, 2020

Add your own answers!

Related Questions

C# find the greatest common divisor

11  Asked on January 5, 2022 by user2723261

   

Time series summary

2  Asked on January 5, 2022 by naanan_

     

Compute frequencies for groups of variables

3  Asked on January 5, 2022 by armel-tedjou

       

How to plot entropart Diversity profiles in ggplot2

1  Asked on January 5, 2022 by alejandra-dip

   

Laravel 6.4.1 SQLSTATE[HY000] [2002] Connection refused

12  Asked on January 5, 2022 by manish-mahajan

         

How to get the key of an element in firebase with AngularFire2?

1  Asked on January 5, 2022 by juan-esteban-rios-gonzalez

         

(PowerShell) How do I filter usernames with Get-EventLog

3  Asked on January 5, 2022 by jeremiah-williams

     

pandas isin() fail between dataframes with objects types columns

1  Asked on January 5, 2022 by franco-milanese

     

Ask a Question

Get help from others!

© 2022 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, MenuIva, UKBizDB, Menu Kuliner, Sharing RPP