【问题标题】:Create DbQuery out of View table从 View 表中创建 DbQuery
【发布时间】:2019-12-16 02:09:51
【问题描述】:

我正在尝试从由 2 个不同表构造的 SQL 视图创建 ExtendedStudent 的 DbQuery(参见下面的代码 SQL)。

我看过以下帖子:

Entity Framework Core Query TypesEF Core 2.1 Query Types 两者都使用了一个带有导航属性的模型,然后成功地从 Fluent Fluent API 中获取它。 但是当我也尝试这样做时,我得到了异常,例如“无效的列名'PrefixId1'

我使用的模型是:

public class ExtendedStudent {

    public int IdNumber {get; set;}

    public string FirstName {get; set;}

    public string LastName {get; set;}

    public virtual Prefix Prefix {get; set;}

    public int Score {get; set;}
}

public class Prefix {

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Id {get ;set;}

    [required]
    public string Name {get; set;}
}

applicationDbContext.cs 文件是:

public class ApplciationDbContext : DbContext{

    DbSet<Prefix> Prefixes {get; set;}

    DbQuery<ExtendedStudent> ExtendedStudents {get ;set;}

    ...

    protected override void OnModelCreating(ModelBuilder builder) {

        builder.Query<ExtendedStudent>.ToView("ExtendedStudent");
        builder.Query<ExtendedStudent>.HasOne<Prefix>().WithMany();
    }
}

最后,我尝试这样获取数据。

var students = applciationDbContext.ExtendedStudents.Include(v => v.Prefix).ToList();

我在 SQL 中创建了 ExtendedStudents 视图,如下所示:


CREATE VIEW [Organization].[ExtendedStudent] AS
SELECT [TableA].[Student].[FirstName]
        ,[TableA].[Student].[LastName]
        ,[TableA].[Student].[PrefixId]
        ,[TableA].[Student].[IdNumber]
        ,[Evaluation].[Student].[Score]
FROM [TableA].[Student] AS [Students]
INNER JOIN [Evaluation].[Student] ON [Evaluation].[Student].StudentId = [TableA].[Student].[IdNumber]

我尝试向 ExtendedStudent 添加 PrefixId 属性,或者添加外键,但没有任何效果。

我收到一个错误提示

“Microsoft.EntityFrameworkCore.dll 中出现了‘System.Data.SqlClient.SqlException’类型的异常,但未在用户代码中处理:‘无效的列名‘PrefixId1’。”

【问题讨论】:

    标签: c# entity-framework-core sql-view ef-core-2.1


    【解决方案1】:

    这里

    builder.Query<ExtendedStudent>.HasOne<Prefix>().WithMany();
    

    .HasOne&lt;Prefix&gt;() 告诉 EF Core 在每一端创建多对一关系没有导航属性。

    但是导航属性 ExtendedStudent.Prefix 已经暗示了关系,因此 EF Core 假定与默认 FK 属性和列名称 PrefixId1 之间存在 second 关系(因为 PrefixId 已经被“其他" 导航属性隐含的关系)。

    要解决这个问题,请将导航属性传递给关系配置:

    builder.Query<ExtendedStudent>.HasOne(e => e.Prefix).WithMany();
    

    【讨论】:

    • 谢谢,这似乎可行,但在我的情况下,我使用了lazyloadingProxies,所以我将虚拟关键字添加到导航属性中,但我收到一条错误消息,提示“从'Castle'的'Prefix'获取值.Proxies.ExtendedStudentProxy --> 无法跟踪“ExtendedStudent”类型的实例,因为它是查询类型,只能跟踪实体类型。你知道为什么要跟踪它吗?
    • 我猜你应该从ExtendedStudent的这个属性中删除virtual,因为ExtendedStudent是查询类型,不应该被代理。至少我是这样阅读错误信息的。
    • 无论如何,这是一个不同的问题,如果您愿意,可以将其作为单独的问题发布。
    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 2013-01-27
    • 2012-01-18
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多