Home > Software design >  EF Core one-to-many relationship with multiple contexts (databases)
EF Core one-to-many relationship with multiple contexts (databases)

Time:10-28

I have contexts with entities like this:

public class CompanyContext : DbContext
{
    public DbSet<StoreModel> Stores { get; set; }
    // Other entities
}
public class DepartmentContext : DbContext
{
    public DbSet<OrderModel> Orders { get; set; }
    // Other entities
}
public class StoreModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<OrderModel> ReceivedOrders { get; set; } 
    public virtual ICollection<OrderModel> PreparedOrders { get; set; }
    public virtual ICollection<OrderModel> IssuedOrders { get; set; }
}
public class OrderModel
{
    public Guid Id { get; set; }
    public string Details { get; set; }
    public StoreModel GettingStore { get; set; } 
    public StoreModel PreparingStore { get; set; }
    public StoreModel IssuanceStore { get; set; }
}

For example a user makes an order in storeA, but wants to receive it in storeC, and it order will preparing in storeB. And I needs a statiscics about store received/prepared/issued orders.

When I try to create a migrations, EF throws exceptions "Unable to determine the relationship represented by navigation 'OrderModel.GettingStore' of type 'StoreModel'" and "Unable to determine the relationship represented by navigation 'StoreModel.IssuedOrders' of type 'ICollection<OrderModel>'". If I understand correctly, this happens because entities are defined in different contexts.

Now I just use next model:

public class OrderModel
{
    public Guid Id { get; set; }
    public string Details { get; set; }
    public Guid GettingStoreId { get; set; } 
    public Guid PreparingStoreId { get; set; }
    public Guid IssuanceStoreId { get; set; }
}

This works fine, but perhaps there are options that allow to create such a structure using navigation properties, with correct relationships between these entities from different contexts(databases).

CodePudding user response:

First, the map of a different database was not placed in tables of different application formats, so think that you have a domain that should be well defined in your application, that way you would have the mapping of your application like this:

public class DomainNameContext: DbContext 
{
    public DomainNameContext(): base() 
    {
    }

    public DbSet<StoreModel> Stores { get; set; }
    public DbSet<OrderModel> Orders { get; set; }
        
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       // config mapping methods
    }
}

another thing, the relation you are using doesn't work so you can't have a repetition of Orders within the same class because this is not one -> many, this statement means that a StoreModel line can have many lines in the OrderModel this way would be like this

public class OrderModel
{
    public Guid Id { get; set; }

    public string Details { get; set; }

    public Guid StoreModeId { get; set; } // this part will show the entity framework that this is the fk it will correlate

    public StoreModel StoreModel { get; set; } 
}

public class StoreModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<OrderModel> OrderModels { get; set; } 
}

see that if you are wanting to have many StoreModel related to many OrderModel then you need to use many -> many which microsoft documentation foresees to use as well

good to map this within its context it is necessary in OnModelCreating to use its mapping like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   // config mapping methods
   modelBuilder.Entity<StoreModel>()
               .HasMany<OrderModel>(g => g.OrderModels )
               .HasForeignkey<Guid>(s => s.StoreModeId )
}

you can have a look at the microsoft documentation enter link description here, enter link description here

now if you need to map between contexts you will have to use dapper to make separate queries in separate bases the entity has support for that in this link enter link description here and then you can make the necessary inner joins so that you can use it but natively this does not exist, I advise you to rethink your database so that it can make more sense to a relational model, perhaps putting types for your StoreModel and OrderModel so you can use the way I wanted the types GettingStore, PreparingStore, IssuanceStore using an enum for this to make it explicit

  • Related