Я хочу запросить представление с коллекцией дочерних таблиц в EF Core 3.1. Возьмите мой упрощенный пример с 3 таблицами:
public class Relation
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Invoice
{
public long Id { get; set; }
public string Reference { get; set; }
public long RelationId { get; set; }
public virtual Relation Relation { get; set; }
public virtual ICollection<InvoiceLine> InvoiceLines { get; set; } = new HashSet<InvoiceLine>();
}
public class InvoiceLine
{
public long Id { get; set; }
public decimal Amount { get; set; }
public decimal Price { get; set; }
public string ArticleReference { get; set; }
public long InvoiceId { get; set; }
public virtual Invoice Invoice { get; set; }
}
Я добавляю представление SQL в свою миграцию:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(@"
CREATE OR ALTER VIEW dbo.InvoiceOverview
AS
SELECT
i.Id
,i.Reference
,r.FistName + ' ' + r.LastName as Name
FROM dbo.Invoices i
INNER JOIN Relations r ON r.Id = i.RelationId");
}
Модель InvoiceView + конфигурация
public class InvoiceView
{
public long Id { get; set; }
public string Reference { get; set; }
public string Name { get; set; }
}
public void Configure(EntityTypeBuilder<InvoiceOverview> builder)
{
builder.HasKey(_ => _.Id);
builder.ToView("InvoiceOverview");
}
Все идет нормально. Все вышеперечисленное работает, но я хочу иметь возможность запрашивать такие строки счета:
Context.InvoiceOverview.AsNoTracking().AsQueryable().Where(_ =>
_.InvoiceLines.Select(invoiceLine => invoiceLine.ArticleReference)
.Any(articleReference => articleReference == "Test").ToListAsync();
Я добавил InvoiceLine-collection в модель InvoiceOverview и обновил config.
public class InvoiceView
{
public long Id { get; set; }
public string Reference { get; set; }
public string Name { get; set; }
public virtual ICollection<InvoiceLine> InvoiceLines { get; set; }
}
public void Configure(EntityTypeBuilder<InvoiceOverview> builder)
{
builder.HasKey(_ => _.Id);
builder.ToView("InvoiceOverview");
builder.HasMany(_ => _.InvoiceLines)
.WithOne()
.HasForeignKey(_ => _.InvoiceId);
}
С приведенной выше конфигурацией я успешно могу выполнить запрос. Единственная проблема, с которой я сейчас сталкиваюсь, заключается в том, что когда я запускаю «Add-Migration», они хотят создать внешний ключ. Невозможно создать внешний ключ для представления (а внешний ключ уже существует в таблице, используемой в представлении).
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddForeignKey(
name: "FK_InvoiceLines_InvoiceOverview_InvoiceId",
table: "InvoiceLines",
column: "InvoiceId",
principalTable: "InvoiceOverview",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
Можно ли явно игнорировать внешний ключ при создании сценария миграции или мне следует написать свою конфигурацию по-другому?