【发布时间】:2014-11-27 18:18:26
【问题描述】:
在我的 C# 应用程序(一个 ASP.NET MVC5 网站)中,我使用 Entity Framework 6 作为我的 ORM,并且我在现有数据库中使用代码优先。数据库是 SQL Server 2012 Standard。
在我的数据库中,我有一个视图 (dbo.vBoardReportLayouts),它用作许多不同元素的连接表。我为此视图创建了一个实体并配置了导航属性。
当我尝试将此实体与 LINQ 实体框架一起使用时,会生成一个 SQL 查询,该查询会尝试使用一个实际不存在的表。具体来说,它正在寻找BoardReportLayoutPages 表。
现在了解所有血腥的细节......
vBoardReportLayouts 视图如下所示:
| ReportID | PageTypeId | PageId | LayoutID |
+----------+------------+--------+----------+
| 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 2 |
| 1 | 1 | 2 | 3 |
| 1 | 1 | 3 | 4 |
| 1 | 2 | 4 | 5 |
| 1 | 2 | 4 | 6 |
| 2 | 1 | 1 | 1 |
| 2 | 1 | 1 | 2 |
| 2 | 1 | 2 | 3 |
| 2 | 1 | 3 | 4 |
| 2 | 2 | 4 | 5 |
| 2 | 2 | 4 | 6 |
BoardReportLayouts 实体类:
[Table("vBoardReportLayouts")]
public partial class BoardReportLayout {
public BoardReportLayout() {
BoardReports = new HashSet<BoardReport>();
PageTypes = new HashSet<PageType>();
Pages = new HashSet<Page>();
PageLayouts = new HashSet<PageLayout>();
}
[Key]
public int BoardReportLayoutId { get; set; }
public int BoardReportId { get; set; }
public int PageTypeId { get; set; }
public int PageId { get; set; }
public int PageLayoutId { get; set; }
public virtual ICollection<BoardReport> BoardReports { get; set; }
public virtual ICollection<PageType> PageTypes { get; set; }
public virtual ICollection<Page> Pages { get; set; }
public virtual ICollection<PageLayout> PageLayouts { get; set; }
}
来自 dbContext 的OnModelCreating() 方法:
modelBuilder.Entity<BoardReportLayout>()
.HasMany(e => e.BoardReports)
.WithMany(e => e.BoardReportLayouts);
modelBuilder.Entity<BoardReportLayout>()
.HasMany(e => e.PageTypes)
.WithMany(e => e.BoardReportLayouts);
modelBuilder.Entity<BoardReportLayout>()
.HasMany(e => e.Pages)
.WithMany(e => e.BoardReportLayouts);
modelBuilder.Entity<BoardReportLayout>()
.HasMany(e => e.PageLayouts)
.WithMany(e => e.BoardReportLayouts);
BoardReport、PageType、Page 和 PageLayout 实体都定义了以下属性:
public virtual ICollection<BoardReportLayout> BoardReportLayouts { get; set; }
执行此 LINQ 查询:
var test = (from l in ppdb.BoardReportLayouts
where l.BoardReportId == 8
select l.Pages).SelectMany(p => p).ToList();
生成此 SQL:
SELECT [Join1].[PageId] AS [PageId],
[Join1].[PageTypeId] AS [PageTypeId],
[Join1].[Name] AS [Name],
[Join1].[ParameterValue] AS [ParameterValue],
[Join1].[SsrsPageParamterValue] AS [SsrsPageParamterValue],
[Join1].[TableOfContentsOrder] AS [TableOfContentsOrder]
FROM [dbo].[vBoardReportLayouts] AS [Extent1]
INNER JOIN (
SELECT [Extent2].[BoardReportLayout_BoardReportLayoutId] AS [BoardReportLayout_BoardReportLayoutId],
[Extent3].[PageId] AS [PageId],
[Extent3].[PageTypeId] AS [PageTypeId],
[Extent3].[Name] AS [Name],
[Extent3].[ParameterValue] AS [ParameterValue],
[Extent3].[SsrsPageParamterValue] AS [SsrsPageParamterValue],
[Extent3].[TableOfContentsOrder] AS [TableOfContentsOrder]
FROM [dbo].[BoardReportLayoutPages] AS [Extent2]
INNER JOIN [dbo].[Pages] AS [Extent3] ON [Extent3].[PageId] = [Extent2].[Page_PageId]
) AS [Join1] ON [Extent1].[BoardReportLayoutId] = [Join1].[BoardReportLayout_BoardReportLayoutId]
WHERE 8 = [Extent1].[BoardReportId]
问题出在[Join1] 表表达式的FROM 子句中。我不确定它为什么要尝试使用表dbo.BoardReportLayoutPages,因为它可以直接从视图连接到Pages 表。表 dbo.BoardReportLayoutPages 不存在,因此会引发异常。
【问题讨论】:
-
[dbo].[vBoardReportLayouts]来自哪里? (注意 v)。 -
vBoardReportLayouts 是我在数据库中创建的视图。 Pages 和 PageLayouts 表中的行都有日期(开始和结束日期),日期指定它们适用于哪些 BoardReports。 BoardReport 实际上是一个月,但在 BoardReport 表中存储了该月的其他属性。我决定使用视图来处理表的连接逻辑,以便我仍然可以在 EF 中使用本机导航属性,但看起来这不会像我希望的那样工作。
标签: c# linq entity-framework entity-framework-6