EF Core:如何查询 SQL 视图

chr*_*rie 2 c# sql-server entity-framework sql-view ef-core-2.1

我的数据库中有一个名为“dbo.Viewtest”的 SQL 视图。此视图组合了其他 2 个具有相同列类型的表的数据。该视图还添加了一列以显示数据源自哪个表。

这是 SQL Server 对象资源管理器中 SQL 视图的样子:

dbo.ViewTest

身份证 | 类型 | 内容 | 地点

1 | H1 | 欢迎!| 家

2 | p | 登录 | 家

3 | h2 | 指南 | 家

1 | H1 | 信息 | 活动

2 | p | 关注 | 活动

该视图由 2 个表创建,其中一个称为“HomeContent”,另一个称为“EventsContent”(因此是位置列)。使用以下代码创建了视图:

protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql("CREATE VIEW ViewTest AS " +
                "SELECT Id, Type, Content, 'Home' location FROM HomeContent UNION ALL " +
                "SELECT Id, Type, Content, 'Evenementen' FROM EvenementenContent");

        }
Run Code Online (Sandbox Code Playgroud)

然后我添加了一个模型类,如下所示:

  [Table("ViewTest")]
    public class TestViewContent
    {
        [Key]
        public int Id { get; set; }
        public string Type { get; set; }
        public string Content { get; set; }
        public string Location { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

最后,我已将其添加到我的 DbContext 中:

 public DbSet<TestViewContent> TestViewContent { get; set; }
Run Code Online (Sandbox Code Playgroud)

现在,事情开始破裂了。当我尝试使用 EF Core 显示此 SQL 视图时,我得到以下损坏的输出:

身份证 | 类型 | 内容 | 地点

1 | H1 | 欢迎!| 家

2 | p | 登录 | 家

3 | h2 | 指南 | 家

1 | H1 | 欢迎 | 家

2 | p | 登录 | 家

如您所见,无论出于何种原因,当我尝试显示 SQL 视图时,当应该显示“事件”表中的数据时,数据会“循环”。因此,无论出于何种原因,它只显示主表中的数据。

我用于显示 SQL 视图的代码是:

 private readonly DbApplicationContext_context;

        public TestViewContentController(DbApplicationContext_context)
        {
            _context = context;
        }

   public async Task<IActionResult> Index()
        {
            return View(await _context.TestViewContent.ToListAsync());
        }
Run Code Online (Sandbox Code Playgroud)

有没有人可以帮助我?如果无法显示 SQL 视图,有没有人知道组合多个表并添加“位置”列以跟踪数据来源的表的更好方法?任何帮助将不胜感激!

Pet*_*r B 5

发生这种情况是因为您放置[Key]了该Id属性,但是在组合两个表时VIEWId列中产生了重复的值。然后 EF Core 可能会“啊,又是Id=1,我已经有了那行,所以我会重用它”。

有三种可能的修复方法:

(1)为保证生成唯一值的 VIEW 定义一个单独的列,然后在 EF Core 中将该列用作[Key].

或者

(2)保持 VIEW 原样,然后在 EF Core 中定义一个复合主键。请注意,EF Core 不支持使用[Key]属性创建复合键,您需要使用 Fluent APIHasKey()函数,在本例中用于LocationId属性。

或者

(3)离开了[Key]干脆,你实际上可能不需要它,在这里的文档描述:无钥匙实体类型