加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 18:03:36 所属栏目:百科 来源:网络整理
导读:我对Entity Framework很新,我有一个关于过滤数据的问题. 我有两个Log实体,分别是:DiskLog和NetworkLog.这些实体都来自于Log实体.这是我的C#应用??程序的一些代码: public class Log { ... }public class DiskLog : Log { ... }public class NetworkLog : L
我对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;

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读