我正在尝试在我的应用程序中的一个Devexpress Grid中实现服务器模式。
网格视图需要可查询的源,所以我不想使用 ToList(( 或 AsEnumerable(将所有数据加载到应用程序内存中(。当我使用 AsQueryable 时,我得到 LINQ to Entities 无法识别该方法...
查询详情:表中的一列(定义(存储为 JSON 字符串。我知道它正在尝试为反序列化方法找到SQL等效项,如果您知道任何替代方案,请提出建议。
下面是查询。
var requestList = (from request in db.request_def
let requestDefinition=new JavaScriptSerializer().Deserialize(request.Definition,typeof(RequestInfo))
let user = db.Users.FirstOrDefault(p => p.PRINCIPAL == requestDefinition.Principal)
let processingAccount =user.EMAIL
select new RequestModel
{
CreatedBy = request.CreatedBy
CreatedOn = request.CreateOn,
Status = request.Status,
ProcessingAccount = processingAccount,
}).OrderByDescending(p => p.CreatedOn).AsQueryable<RequestModel>();
您似乎在数据库中存储了一个 JSON 字符串,但您仍然希望将其"联接"到另一个表。您的选项可能仅限于以下选项之一:
- 将整个表拖到内存中,反序列化并在那里执行 JOIN。这可能会非常慢 - 不要这样做。
- 移动到设计为像这样查询的数据存储(即MongodDB,DocumentDB等(
- 将 JSON 插入表中时,复制值(即
Principal
( 到它自己的列中,以便您可以执行经典的 SQL 联接,具体化代码中的数据,然后对其进行反序列化。 - 如果您运行的是SQL Server 2016或更高版本,那么您应该能够使用SQL Server JSON查询对数据库运行原始SQL查询。
从查询中排除 ProcessingAccount 字段,以便能够在服务器端执行它并检索数据。而是将"定义"字段添加到"请求模型"。然后,添加一个未绑定的列,您将在其中手动加载处理帐户数据。
为此,请处理 CustomUnboundColumnData 事件。在事件处理程序中,使用 ASPxGridColumnDataEventArgs.GetListSourceFieldValue 方法获取当前记录的定义,对其进行反序列化,然后从数据库中加载用户以获取处理帐户。
为了减少数据库查询量,最好检索当前页面中所有记录的 Definition 值,并批量加载所有相关用户。可以在第一次调用 CustomUnboundColumnData 事件处理程序时执行此操作,并将结果存储在局部变量中,以便在后续调用中使用它。