Линк-матрица отношения многие ко многим со значениями по умолчанию - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь создать матрицу (так сказать) отношений «многие ко многим». Однако мне нужно иметь возможность возвращать значения по умолчанию (например, LEFT OUTER JOIN), когда в таблице сопоставлений нет записей.

Например, у меня есть две модели: МаркетПрофиль и Предложение

public class MarketProfiles : BaseModel
{
    [Key]
    public int ProfileId { get; set; }

    [Required, StringLength(50)]
    public string Name { get; set; }
}

public class Offering : BaseModel
{
    public int OfferingId { get; set; }

    [Required, StringLength(50)]
    public string Name { get; set; }

    [Required, StringLength(20)]
    public string ShortName { get; set; }       
}

И модель ассоциации Цель:

public class Target
{
    [Key, Column(Order = 0)]
    public int OfferingId { get; set; }
    public virtual Offering Offering { get; set; }

    [Key, Column(Order = 1)]
    public int ProfileId { get; set; }
    [ForeignKey("ProfileId")]
    public virtual MarketProfiles Profile { get; set; }

    [Column(TypeName = "money")]
    public decimal? InitialSales { get; set; }

    [Column(TypeName = "money")]
    public decimal? AnnualSales { get; set; }
}

Теперь я хочу иметь возможность создать таблицу с MarketProfiles, идущими по строкам, и предложениями, проходящими по столбцам, что я могу сделать, как только модель ассоциации будет сохранена в первый раз. Но я хочу, чтобы таблица отображалась, когда записи не были созданы, поэтому у меня есть текстовое поле для полей InitialSales и AnnualSales, в которые должны быть введены значения.

Я могу создать таблицу, используя следующий запрос (если в таблице сопоставлений есть значения)

viewModel.Matrix = (from p in _repository.GetAll<MarketProfiles>()
                    join t in _repository.GetAll<Target>() on p.ProfileId equals t.ProfileId into ts
                     from targets in ts.DefaultIfEmpty()
                    join o in _repository.GetAll<Offering>() on targets.OfferingId equals o.OfferingId into off
                     from offs in off.DefaultIfEmpty()
                     group targets by p into g
                     select new MatrixViewModel
                     {
                          Name = g.Key.Name,
                          ProfileId = g.Key.ProfileId,
                          Targets = (from t in g
                                    select new TargetViewModel
                                    {
                                         AnnualSales = t.AnnualSales,
                                         InitialSales = t.InitialSales,
                                         OfferingId = t.OfferingId,
                                         OfferingName = t.Offering.ShortName
                                     }).ToList()
                      })

Возможно ли это даже с Linq? Я могу создать его с помощью динамического Sql, но это просто ужасно, и я бы предпочел использовать Linq.

...