Using linq c# how can I select using a condition two different lists

Viewed 88

Here are my DataModels:

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; }
}

The relation between the two tables in many to one, an Alert have multiple generatedAlerts.

I have two cases:

  1. Is to retreive a list of generated alert where read = true, if the property ShowOldAlerts in alert is set to false.
  2. Is to retreive all the alerts if the property ShowOldAlerts in Alert is set to true. But I have to return the all this is one list.

I have tried doing this but it doesn't work:

        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();
2 Answers

Maybe you are looking for this.

Filtere where

  • x.Alert.ShowOldAlerts == true

    or

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

Example

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();

If you need the results separated, it's probably best to still keep the one query (one round trip to the database), however you can filter the results after the fact.

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

var read = results.Axcept(alerts ); 

For the first case which retrieves generated alerts if Read is true and ShowOldAlerts is false. If I understood the question correctly, this should work.

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

For the second case where you only retrieve the generated alerts only if ShowOldAlerts is false.

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

To return as one list, the conditions seem awkward, but here it is

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