Отображение базовых свойств Entity Framework - PullRequest
0 голосов
/ 26 октября 2018

Здравствуйте, у меня проблема с моим отображением.

У меня есть классы в иерархической структуре:

  1. TaxYear
  2. Владелец
  3. EconomyUnit
  4. Отчет
  5. ReportItem
  6. Счет

Все эти классы имеют базовый класс "BaseEntity", а также родительское свойство и свойство parent_id.

Родительское свойство счета-фактуры не относится к типу «ReportItem», поскольку «Onwer» имеет отдельный список счетов-фактур, поэтому тип «BaseEntity».

Это прекрасно работает, я могу использовать в качестве родителя "ReportItem" и "Владелец".

Но теперь я хочу «переместить» счета-фактуры между родителями.В данный момент только из «ReportItem» в «ReportItem».

Установите новый родительский элемент:

foreach (var invoice in oldReportItem.Invoices)
{
    invoice.Parent = newReportItem;
}
ctx.SaveChanges();

Это работает без ошибок, но не правильно.EF создал три столбца для моего родительского свойства.

  • Owner_Id
  • ReportItem_Id
  • Parent_Id

Если вы вставите счет-фактуру, то оба столбца получат одинаковый идентификатор.Работает нормально, но если вы установите нового родителя, то для "Onwer_Id" или ReportItem_Id будет установлено значение null, а Parent_Id будет обновляться только.

Моя проблема.Я думаю, что мое отображение неверно.Кто-нибудь может мне помочь?

Fluent-Api

modelBuilder.Entity<ReportItem>()
    .HasOptional(p => p.Parent)
    .WithMany(p => p.Items)
    .HasForeignKey(k => k.ParentId)
    .WillCascadeOnDelete(false);

BaseEntity:

public abstract class BaseEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public abstract String GetName();

    public DateTime? CreateDate { get; set; }
    public DateTime? LastEditDate { get; set; }

    public BaseEntity DeepCopy()
    {
        return (BaseEntity)MemberwiseClone();
    }
}

Владелец:

public class Owner : BaseEntity
{
    public Owner()
    {
        Items = new ObservableCollection<EconomyUnit>();
        PrivateInvoices = new ObservableCollection<Invoice>();
    }

    [Required]
    public String Name { get; set; }

    [Required]
    public TaxYear Year { get; set; }
    public Guid? YearId { get; set; }

    public ICollection<EconomyUnit> Items { get; private set; }
    public ICollection<Invoice> PrivateInvoices { get; private set; }

    public override string GetName()
    {
        return Name;
    }
}

ReportItem:

public class ReportItem : BaseEntity
{
    public ReportItem()
    {
        Items = new ObservableCollection<Invoice>();
    }

    [Required]
    public String Name { get; set; }

    public ICollection<Invoice> Items { get; private set; }

    public Guid? ParentId { get; set; }
    public Report Parent { get; set; }
}

Счет:

public class Invoice: BaseEntity
{
    public String Name { get; set; }

    public Guid? ParentId { get; set; }

    public BaseEntity Parent { get; set; }

}

Спасибо, Lyror

1 Ответ

0 голосов
/ 26 октября 2018

Хорошо, давайте начнем с ОП.

У меня есть классы в иерархической структуре:

TaxYear Владелец EconomyUnit Report ReportItem Invoice

В ваших структурах классов указано, что TaxYear является необязательным, поэтому он не может быть родительским (по определению). Некоторые из ваших классов отсутствуют, поэтому я не могу определить, есть ли какие-либо другие недостатки. Принимая ваше утверждение за чистую монету, ваши занятия будут выглядеть примерно так (лишние поля удалены для ясности)

public abstract class BaseEntity - Unchanged

public class Owner : BaseEntity
{
    // Parent navigation    
    public Guid YearId { get; set; }
    public virtual TaxYear Year { get; set; }

    // Child navigation
    public virtual ICollection<EconomyUnit> Units { get; private set; }
}

public class EconomicUnit : BaseEntity
{
    // Parent navigation    
    public Guid OwnerId { get; set; }
    public virtual Owner Owner { get; set; }

    // Child navigation
    public virtual ICollection<Report> Reports { get; private set; }
}

public class Report : BaseEntity
{
    // Parent navigation    
    public Guid UnitId { get; set; }
    public virtual EconomicUnit Unit { get; set; }

    // Child navigation    
    public virtual ICollection<ReportItem> Items { get; private set; }
}

public class ReportItem : BaseEntity
{
    // Parent navigation    
    public Guid ReportId { get; set; }
    public virtual Report Report { get; set; }

    // Child navigation    
    public virtual ICollection<Invoice> Invoices { get; private set; }
}

public class Invoice : BaseEntity
{
    // Parent navigation    
    public Guid ReportItemId { get; set; }
    public virtual ReportItem ReportItem { get; set; }
}

Если вы хотите просмотреть список счетов-фактур для Владельца, попробуйте это:

dbContext.Invoices.Where(a => a.ReportItem.Report.EconomicUnit.Owner.Id == <parameter>).Include(b => b.ReportItem.Report.EconomicUnit.Owner.TaxYear).ToList();

Конечно, вы можете выбрать в новом объекте DTO инвертирование отношения Владелец ==> Счета.

...