Запрос связанной сущности - PullRequest
0 голосов
/ 18 января 2019

У меня есть база данных с тобой - например, «Организации», «Места» и «Организация». Организации хранят информацию о компаниях, Locations хранит информацию об адресах офисов, а OrganisationLocations хранит информацию об отношениях «многие ко многим» о компаниях и их адресах. Например, Компания A может быть местоположениями X и Y, Компания B может находиться в местоположениях Y и Z.

Это сгенерированные классы

public partial class Locations
{
    public Locations()
    {
        OrganisationLocations = new HashSet<OrganisationLocations>();
    }

    public long Id { get; set; }
    public string Description { get; set; }
    public string City { get; set; }
    public string Street { get; set; }
    public string PostCode { get; set; }
    public string Name { get; set; }

    public virtual ICollection<OrganisationLocations> OrganisationLocations { get; set; }
}
public partial class Organisations
{
    public Organisations()
    {
        OrganisationLocations = new HashSet<OrganisationLocations>();
    }

    public long Id { get; set; }
    public string Name { get; set; }
    public string Owner { get; set; }
    public string ContactName { get; set; }
    public string Email { get; set; }
    public string Telephone { get; set; }

    public virtual ICollection<OrganisationLocations> OrganisationLocations { get; set; }

}
public partial class OrganisationLocations
{
    public long Id { get; set; }
    public long OrganisationId { get; set; }
    public long LocationId { get; set; }

    public virtual Locations Location { get; set; }
    public virtual Organisations Organisation { get; set; }
    }

Контекст БД выглядит так:

public class PfApiContext : DbContext
{

    public PfApiContext(DbContextOptions<PaymentAPIContext> options)
            : base(options)
    {
    }

    public DbSet<Locations> Locations { get; set; }
    public DbSet<Organisations> Organisations { get; set; }
    public virtual DbSet<OrganisationLocations> OrganisationLocations { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<OrganisationLocations>(entity =>
        {

             entity.HasOne(d => d.Location)
                .WithMany(p => p.OrganisationLocations)
                .HasForeignKey(d => d.LocationId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_84m7dbl1gv1p6tg1wquwm8j5u");

            entity.HasOne(d => d.Organisation)
                .WithMany(p => p.OrganisationLocations)
                .HasForeignKey(d => d.OrganisationId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_r0mkkndb6c2tr9nl0rgjm068t");
        });

    }
}

Как я могу получить, например, все данные о компаниях для всех компаний в Месте X? В момент, когда я запрашиваю это, я на самом деле знаю LocationID, поэтому SQL будет

SELECT  * FROM [dbo].[Organisations] WHERE Id IN (SELECT [OrganisationId] FROM [dbo].[OrganisationLocations] WHERE [LocationId] = 1)

Это, вероятно, действительно просто, и я просто глуп, но я новичок в EFCore и LINQ, и синтаксис этого заставляет меня чесать голову. Выбор местоположения на основе названия местоположения, которое я могу понять

var locationUsers = await _pfApiContext.UserLocations.Where
    (o => o.LocationName == locationName).ToListAsync();

но меня смущает нечто ужасное.

Спасибо за любую помощь

1 Ответ

0 голосов
/ 18 января 2019

Я бы удалил виртуальные коллекции и объекты из всех трех классов, а затем удалил поле Id (при условии, что это первичный ключ) в таблице OrganisationLocations. Поля OrganisationId и LocationId в OrganisationLocations должны быть как первичными ключами, так и внешними ключами, чтобы сделать связь «многие ко многим» между OrganisationLocations, Locations и Organization. Затем вы можете использовать Linq, чтобы выполнить простой запрос на соединение, чтобы получить информацию, которую вы ищете. Например:

            var orgs = (from ol in PfApiContext.OrganisationLocations
                        inner join o in PfApiContext.Organisation on o.Id equals ol.OrganisationId
                        inner join l in PfApiContext.Locations on ol.LocationId equals l.Id
                        where ol.LocationId = 1
                        select new Organisation()
                        {
                            Id = o.Id,
                            Name = o.Name,
                            Owner = o.Ower,
                            etc...

                        }
...