【问题标题】:Using linq c# how can I select using a condition two different lists使用 linq c# 如何使用条件选择两个不同的列表
【发布时间】:2021-02-05 23:23:23
【问题描述】:

这是我的数据模型:

public class GeneratedAlertDataModel : BaseEntity
{
    /// <summary>
    /// the alert that will be generated 
    /// from configuration of alert
    /// </summary>
    public string AlertText { get; set; }
    public bool Read { get; set; }
    public AlertDataModel Alert { get; set; }
    public DateTime ReceivedDate { get; set; }
    public bool Completed { get; set; }
}

public class AlertDataModel : BaseEntity
{
    [Required]
    [MaxLength(250)]
    public string Designation { get; set; }

    [Required]
    public PriorityLevel PriorityLevel { get; set; }

    public bool ShowOldAlerts { get; set; }
}

两个表之间的关系是多对一的,一个Alert有多个生成的Alerts。

我有两种情况:

  1. 如果警报中的属性 ShowOldAlerts 设置为 false,则检索生成的警报列表,其中 read = true。
  2. 如果警报中的属性 ShowOldAlerts 设置为 true,则检索所有警报。 但我必须返回所有这些都是一个列表。

我尝试过这样做,但它不起作用:

        var generatedAlertDbQuery = _context.GeneratedAlerts.Include(a => a.Alert)
            // if set ShowAlert to false, get only the not viewed generated alerts
            .Where(a => a.Alert.ShowOldAlerts).Select(a => a)
            // if set ShowAlert to true, get only the not viewed generated alerts
            .Where(a => !a.Alert.ShowOldAlerts).Select(a => a).Where(a => !a.Read)

            .OrderBy(a => a.ReceivedDate) // Ordered by the receive date
            .Take(take) // Taking maximum (will be configured in client)
            .AsQueryable();

        var generatedAlertResponse = await generatedAlertDbQuery.Select(a => new GeneratedAlertResponse
        {
            Id = a.Id,
            Alert = _mapper.Map<AlertInfoResponse>(a.Alert),
            ReceivedDate = a.ReceivedDate,
            Completed = a.Completed,
        }).ToListAsync();

【问题讨论】:

  • 也许我不明白这个问题......两个实体有什么关系?你有一个Alert 对象列表;有些人可能拥有真实的财产;其他为假。这些值如何影响您选择all 还是some 生成的警报?
  • 关系是多对一的,alerts有多个generateAlerts,所以alert类基本上就是一个配置,产生多个alerts

标签: c# linq asp.net-core


【解决方案1】:

也许你正在寻找这个。

过滤位置

  • x.Alert.ShowOldAlerts == true

  • x.Alert.ShowOldAlerts == false &amp;&amp; Read == false

示例

var results = _context.GeneratedAlerts
    .Include(a => a.Alert)
    .Where(x => x.Alert.ShowOldAlerts || !x.Read)
    .Select(a => new GeneratedAlertResponse
    {
        Id = a.Id,
        Alert = _mapper.Map<AlertInfoResponse>(a.Alert),
        ReceivedDate = a.ReceivedDate,
        Completed = a.Completed
        ...
    }.ToList();

如果您需要分离结果,最好仍然保留一个查询(到数据库的一次往返),但是您可以在事后过滤结果。

var alerts = results.Where(x => x.Alert.ShowOldAlerts);

var read = results.Axcept(alerts ); 

【讨论】:

  • 如果我必须在哪里过滤:x.Alert.ShowOldAlerts == true(获取所有列表)以及如果x.Alert.ShowOldAlerts == false &amp;&amp; Read == false
  • @Hasagiii 已更新...您需要在 2 个单独的结果中使用它吗?
  • 是的,非常好。
  • 你能准确地告诉我你所说的分别是什么意思吗?
  • @Hasagiii 我们如何旋转这个。代码你运行了吗,它工作了吗?
【解决方案2】:

如果Read 为真且ShowOldAlerts 为假,则检索生成的警报的第一种情况。如果我正确理解了这个问题,这应该可行。

var alerts = _context.GeneratedAlerts
    .Where(c => c.Read && !c.Alert.ShowOldAlerts);

对于第二种情况,仅当 ShowOldAlerts 为 false 时才检索生成的警报。

var alerts = _context.GeneratedAlerts
         .Where(c => c.Alert.ShowOldAlerts);

要作为一个列表返回,条件似乎很尴尬,但就是这样

var alerts = _context.GeneratedAlerts
    .Where(c => (c.Read && !c.Alert.ShowOldAlerts) || c.Alert.ShowOldAlerts);

【讨论】:

  • 我应该把它们都连接起来吗?
  • @Hasagiii 我不明白你所说的连接是什么意思。
  • 我的意思是将它们作为一个列表返回
  • 谢谢它的工作,这完全是关于逻辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2015-05-16
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多