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

Copy each cell in a range to multi-cell range

2  Asked on November 29, 2021 by preston-richardson

   

How to make dynamic custom textarea with jquery?

3  Asked on November 29, 2021 by david-noya

     

private static field Java

3  Asked on November 29, 2021

         

unordered_map excess calls to hash function

4  Asked on November 29, 2021 by amir-kirsh

   

cant load static file in django

1  Asked on November 29, 2021

       

Ask a Question

Get help from others!

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