我想用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();
我在InvoiceOverview模型中添加了InvoiceLine-collection并更新了配置。
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);
}
使用上述配置,我可以成功运行查询。 我现在遇到的唯一问题是,当我运行“添加迁移”时,他们想创建一个外键。无法为视图创建外键(并且该视图所使用的表上已存在外键)。
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddForeignKey(
name: "FK_InvoiceLines_InvoiceOverview_InvoiceId",
table: "InvoiceLines",
column: "InvoiceId",
principalTable: "InvoiceOverview",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
在生成迁移脚本时是否可以显式忽略外键,还是应该以不同的方式编写配置?
答案 0 :(得分:0)
我在Entity Framework Core 2.2 : Disable migrations for specific entities找到了解决方案
public void Configure(EntityTypeBuilder<InvoiceOverview> builder)
{
builder.HasKey(_ => _.Id);
builder.ToView("InvoiceOverview");
builder.HasMany(_ => _.InvoiceLines)
.WithOne()
.HasForeignKey(_ => _.InvoiceId);
if (MigrationHelper.IsMigrationOperationExecuting())
{
builder.Ignore(x => x.InvoiceLines);
}
}
public static class MigrationHelper
{
public static bool IsMigrationOperationExecuting()
{
var commandLineArguments = Environment.GetCommandLineArgs();
string[] orderedMigrationArguments = { "migrations", "add" };
for (var i = 0; i <= commandLineArguments.Length - orderedMigrationArguments.Length; i++)
{
if (commandLineArguments.Skip(i).Take(orderedMigrationArguments.Length).SequenceEqual(orderedMigrationArguments))
return true;
}
return false;
}
}