c# – 如何动态构建Entity Framework查询?

前端之家收集整理的这篇文章主要介绍了c# – 如何动态构建Entity Framework查询?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我对Entity Framework很新,我有一个关于过滤数据的问题.

我有两个Log实体,分别是:DiskLog和NetworkLog.这些实体都来自于Log实体.这是我的C#应用​​程序的一些代码

public class Log { ... }
public class DiskLog : Log { ... }
public class NetworkLog : Log { ... }

public enum LogType
{
    NotInitialized = 0,Disk,Network
}

public List<Log> GetWithFilter(
    Guid userKey,int nSkip,int nTake,DateTime dateFrom = DateTime.MinValue,DateTime dateTo = DateTime.MaxValue,LogType logType = LogType.NotInitialized,int computerId = 0)
{
    // need to know how to optimize ...

    return ...
}

当然,我已经创建了工作的应用程序和数据库表.我想做的是使函数GetWithFilter工作.我有几种执行方式:

>如果logType == LogType.Disk&&& computerId <= 0(这意味着查询中不需要使用computerId参数,仅选择DiskLog实体)
>如果logType == LogType.Disk&&& computerId> 0(意味着我必须使用computerId参数,仅选择DiskLog实体)
>如果logType == LogType.NotInitialized&& computerId <= 0(不需要使用computerId和logType,只需选择所有实体,DiskLog和NetworkLog)
>如果logType == LogType.NotInitialized&& computerId> 0(选择指定计算机的所有类型的日志)
>如果logType == LogType.Network&& computerId <= 0(选择所有NetworkLog实体)
>如果logType == LogType.Network&& computerId> 0(选择指定计算机的所有NetworkLog实体)

你可以看到,有很多可用的选项.而且我写了6个这样的查询

1.

context.LogSet
    .OfType<DiskLog>
    .Where(x => x.Computer.User.UserKey == userKey)
    .Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
    .OrderByDescending(x => x.Id)
    .Skip(nSkip)
    .Take(nTake)
    .ToList();

2.

context.LogSet
    .OfType<DiskLog>
    .Where(x => x.Computer.User.UserKey == userKey)
    .Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
    .Where(x => x.Computer.Id == computerId)
    .OrderByDescending(x => x.Id)
    .Skip(nSkip)
    .Take(nTake)
    .ToList();

3.

context.LogSet
    .Where(x => x.Computer.User.UserKey == userKey)
    .Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
    .OrderByDescending(x => x.Id)
    .Skip(nSkip)
    .Take(nTake)
    .ToList(); // simplest one!

4.

context.LogSet
    .Where(x => x.Computer.User.UserKey == userKey)
    .Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
    .Where( x => x.Computer.Id == computerId)
    .OrderByDescending(x => x.Id)
    .Skip(nSkip)
    .Take(nTake)
    .ToList();

5.

context.LogSet
    .OfType<NetworkLog>
    .Where(x => x.Computer.User.UserKey == userKey)
    .Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
    .OrderByDescending(x => x.Id)
    .Skip(nSkip)
    .Take(nTake)
    .ToList();

6.

context.LogSet
    .OfType<NetworkLog>
    .Where(x => x.Computer.User.UserKey == userKey)
    .Where(x => x.DateStamp >= dateFrom && x.DateStamp < dateTo)
    .Where( x => x.Computer.Id == computerId)
    .OrderByDescending(x => x.Id)
    .Skip(nSkip)
    .Take(nTake)
    .ToList();

那么问题是如何优化代码?在哪里可以使它更好.

解决方法

您可以轻松使用查询编译.

你首先从查询开始.

IQueryable<Log> query = context.LogSet;

他们组成子查询.

if (logType == LogType.Disk)
{
    query = query.OfType<DiskLog>(); // not sure if you need conversion here
} 
else if (logType == LogType.Network)
{
    query = query.OfType<NetworkLog>(); // not sure if you need conversion here
}

query = query.Where(x => x.Computer.User.UserKey == userKey);

if (computerId != 0)
   query = query.Where( x => x.Computer.Id == computerId);

// .. and so on

query = query.OrderByDescending(x => x.Id).Skip(nSkip).Take(nTake);

return query.ToList(); // do database call,materialize the data and return;

而当没有值时,我会推荐使用可空值类型.

猜你在找的C#相关文章