Abdul
Abdul

Reputation: 561

Linq to check before it creates select

I have a Linq query as follows

NOVId = (v.NOVId != null ? new List<int> { v.NOVId ?? default(int) }
: (from n in novs where n.Violations.Any(a => a.ViolationId == v.ViolationId) select v.NOVId ?? default(int)).ToList())

, what I want is, it is failing at n.Violations or a.ViolationId, since there are some novs which do not have violations, how can I fix this? that it shouldn't fail, just goes through without errors or exceptions - means this shhould select only if n.Violations has violations otherwise just return either 0 or null - any help please? Thanks in advance.

Upvotes: 2

Views: 132

Answers (2)

StepUp
StepUp

Reputation: 38174

This construction v.NOVId ?? default(int) can be removed as there is no need to use default(int) as you've already checked v.NOVId != null:

var NOVIds = v.NOVId != null ? 
    new List<int> { v.NOVId }
  : (from n in novs where n.Violations.Any(a => a.ViolationId == v.ViolationId) 
        select v.NOVId).ToList()

UPDATE:

To check whether a.ViolationId != null and v.ViolationId != null, you can use the following query:

var NOVIds = v.NOVId != null ? 
    new List<int> { v.NOVId }
  : (from n in novs where n.Violations.Any(a => 
     (a.ViolationId != null && v.ViolationId != null) 
     ? (a.ViolationId == v.ViolationId) : false) 
        select v.NOVId).ToList()

UPDATE 1:

It is possible to use condition n.Violations != null, to check whether n.Violations is not null:

var NOVIds = v.NOVId != null ? 
    new List<int> { v.NOVId }
  : (from n in novs where n.Violations != null && n.Violations.Any(a => 
     (a.ViolationId != null && v.ViolationId != null) 
     ? (a.ViolationId == v.ViolationId) : false) 
        select v.NOVId).ToList()

Upvotes: 1

Thomas Heijtink
Thomas Heijtink

Reputation: 492

Make sure that in the constructor of Nov you instantiate your enumeration.

public class Nov
{
    public Nov()
    {
        Violations = Enumerable.Empty<Violation>();
    }

    public IEnumerable<Violation> Violations { get; }
}

So you know that there is always a reference to an empty enumeration of violations.

If it is a complex object or when the object is instantiated many times throughout the code or there are many different ways you can construct this object (you can also use the builder pattern here) you can also use a factory here the following way.

public class NovFactory
{
    public INov Create()
    {
        return new Nov
        {
            Violations = Enumerable.Empty<Violation>();
        }
    }
}

public interface INov
{
    IEnumerable<Violation> Violations { get; }
}

public class Nov : INov
{
    public IEnumerable<Violation> Violations { get; set; }
}

Upvotes: 1

Related Questions