我正在使用实体框架(模型优先)和映射到视图的实体。该视图位于 SQL Server 中,但使用链接服务器与 SQL Server 和 Oracle 表连接。这已经存在了几个月,没有任何问题。
我已经更新了这个问题。 该问题是由 Oracle 链接服务器引起的。如上所述,我的视图使用链接服务器(和 OpenQuery)连接 SQL Server 表和 Oracle 表。作为测试,我将所有数据移至本地表,然后更改视图以从该表中进行选择,从而使链接服务器退出进程。现在一切正常 - 我没有收到“未找到数据”错误。
首先,我使用 Linq 查询来获取不同的行(父母)。然后,在迭代时,我使用第二个链接查询(在原始对象上)来获取每一行的子项。正是第二个 Linq 查询失败了——只有当我访问第二行时它才会失败。当只有一行返回时,它可以工作。当返回多行时,我可以访问第一行,但不能再访问了。
使用链接服务器(特别是 Oracle)和实体框架是否有问题?
以下是详细信息:
该视图表示与驻留在批处理中的文件集合相关的数据。批次名称可能会重复,因为每个批次可以有多个文件。这是一个示例:
File1
Batch1 File1 Bacth2
File3 Batch2
我有一个名为 LatestFileResult 的模型优先实体,它映射到 Oracle/SqlServer 视图。
在我的视图模型中,我有一个方法可以为有错误的批次获取不同的批次(Batch1、Batch2)。它在下面的代码示例中称为 BatchErrors。我从没有限制的 LatestFileResult 实体开始。
在我看来,我成功地迭代了批次并显示了数据。这按预期工作。
在每次迭代中,我都需要获取组成该批次的文件并遍历它们。在 viewModel 中,我有一个名为 FilesInBatch 的方法,它接受一个 batchID 并返回具有该 batchID 的行。它还从没有限制的 LatestFileResult 实体开始。
在我看来,在第一次外部迭代中,一切都按预期工作。它调用 FilesInBatch(只有一行)并访问返回的值。在第二次外部迭代中,我在 forEach 行本身上调用 FilesInBatch 时出现错误(在分配上 - 在退出 FilesInBatch 之后)。应该返回两个项目,但在获取文件时发生错误 - 在 foreach 语句中。这仅在超过 1 行时才会失败。我可以访问第一行,但不能访问第二行。foreeach 将它们全部拉出(包括第二个)并引发异常。错误是:
无法从链接服务器“OM_ORACLE”的 OLE DB 提供程序“OraOLEDB.Oracle”获取行的数据。链接服务器“OM_ORACLE”的 OLE DB 提供程序“OraOLEDB.Oracle”返回消息“ORA-01403:
我知道这意味着什么——这不是问题所在。 但是,有此查询的数据。这不是一个准确的错误。在 FilesInBatch 中,我有两个变量获得计数,它们在调用时都显示 2,导致“未找到数据”错误。
ViewModel 中的两种方法都使用实体框架 LatestFileResult 对象,没有任何限制。
- 我在第一种方法中获得的 batchID 不可能在第二种方法中不存在。
- fileInBatch 方法在方法内显示 2 个文件 - 然后在视图中崩溃并显示“未返回数据”。如果没有数据,我如何获得 2 的计数。
我是 MVC 和 Linq 的新手。我怀疑关于 Linq 和延迟绑定有一些我不明白的地方。
现在是代码。
首先,视图模型。
这是获取不同批次的方法:
public IQueryable<LatestFileResult> BatchErrors
{
get
{
IQueryable<LatestFileResult> results = new Domain.Concrete.ResultsRepository().LatestFileResult;
//Get one batchFileID from each batch
var x = from row in results
where row.batchErrorCode > 0
group row by new { row.batchID } into single
let maxChild = single.Max(row => row.batchFileID)
select new { maxChild };
//Get one batch for each batchFileID
IQueryable<LatestFileResult> batches = from row in results
where x.Any(fileID => fileID.maxChild == row.batchFileID)
orderby row.officeName, row.orgName, row.lastName, row.firstName, row.fileNumber, row.batchErrorCode, row.StartDate
select row;
return batches;
}
}
这是根据 bacthID 获取文件的方法。
public IQueryable<LatestFileResult> FilesInBatch(Int32 batchID)
{
IQueryable<LatestFileResult> results = new Domain.Concrete.ResultsRepository().LatestFileResult;
var theCountBefore = results.Where(r => r.batchID == batchID);
IQueryable<LatestFileResult> theFiles = from row in results
where row.batchID == batchID
select row;
int theCountAfter = theFiles.Count();
return theFiles;
}
注意变量 theCountBefore 和 theCountAfter。他们表明我有关于崩溃的呼叫的数据。另外,请注意这两种方法都以相同的 LatestFileResult 实体对象开头。
这是视图的代码。
@foreach (Domain.Entities.LatestFileResult row in Model.BatchErrors)
{
<tr>
<td>@Html.DisplayFor(modelItem => row.batchName)</td>
</tr>
<tr>
<td >
@foreach (var file in Model.FilesInBatch(row.batchID))
{
@Html.DisplayFor(modelItem => file.fileName)
<br />
}
</td>
</tr>
}
此行发生错误:@foreach(Model.FilesInBatch(row.batchID)中的var文件)。使用调试器,我从 Model.FilesInBbatch 调用返回(在方法中显示正确的计数)。然后调试器突出显示“in”,当我跨步时,我得到了错误。