1

I have an observable collection of Bids, class structure below.

public class Bids
{       
        public DateTime StartDateTimeLocal { get; set; }
        public DateTime EndDateTimeLocal { get; set; }                

        public decimal Bid5 { get; set; }
    public decimal Price5  { get; set; }
        public decimal Bid4 { get; set; }
    public decimal Price4  { get; set; }
        public decimal Bid3 { get; set; }
    public decimal Price3  { get; set; }
        public decimal Bid2 { get; set; }
    public decimal Price2  { get; set; }
        public decimal Bid1 { get; set; }
    public decimal Price1  { get; set; }
}

I have an observable collection

public ObservableCollection<Bid> Bids {get; set;}

Bids collection looks like below,

StartDateTimeLocal EndDateTimeLocal Bid5 Price5 Bid4 Price4 Bid3 Price3 Bid2 Price2 Bid1 Price1
2014-02-14 23:00 2014-02-14 23:30 0 0 0 0 0 0 50 10 100 100
2014-02-14 23:30 2014-02-15 00:00 0 0 0 0 0 0 10 300 200 10
2014-02-15 00:00 2014-02-15 00:30 0 0 0 0 0 0 100 30 0 10
2014-02-15 03:00 2014-02-15 01:00 0 0 0 0 0 0 30 100 0 0

I need to validate the data in the observable collection is valid as per the rules...

  1. Bid 2 should only have a value if bid 1 has a value. So, unless there is a bid 1 a non zero value in bid 2 is invalid. Similarly a a value in bid1, bid2, bid3 is fine but if bid4 doesn't have a value then a value in bid5 is invalid.
  2. Bid prices must be constant or increasing as you go up bids. So, bid 2 price should either be same or greater than bid 1 price.

In the above sample, - The 3rd & 4th row are incorrect since Bid1 doesn't have a value but Bid2 does.
- The 2nd row is correct since Bid1 has a value and hence Bid2 having a value is fine, The price of Bid2 > Bid1. While Row 1 is
incorrect since Price of Bid 2 is < Price of Bid 1

Can some one please advise an approach to perform this validation.

Tarun Arora
  • 4,692
  • 4
  • 30
  • 40
  • LINQ stands for Language INtegrated Query. It can't perform any validations for you. If you provide some more details, there are options available. Are you trying to validate when creating the objects, are you trying to validate at the UI, are you trying to validate when inserting DB rows, etc? – Justin Niessner Feb 14 '14 at 18:57
  • The object Bids is bound to a datagrid, i am performing these validations on a button click. The object already exists and the values are in the object. If the validations fail, i'll be reporting this back to the user, if not, save it to the database. – Tarun Arora Feb 14 '14 at 19:01
  • 1
    Have you tried writing non-LINQ validation before trying to use LINQ? – MarcinJuraszek Feb 14 '14 at 19:02
  • 1
    Use spaces instead of tabs to make your grid look nice in your post. Also wrap the grid with the tags `
    ` instead of using the 4 spaces method to turn it in to a section of preformatted text without the code highlighting. You may want to check out [this site](http://www.sensefulsolutions.com/2010/10/format-text-as-table.html) made by the user [Senseful](http://stackoverflow.com/users/35690/senseful) that will do some of the formatting like tabs to spaces for you.
    – Scott Chamberlain Feb 14 '14 at 19:12

2 Answers2

2

The Bids object itself is not a collection (does not implement any LINQ-related interface, like IEnumerable), so I have no idea why you're trying to use LINQ to validate the object.

Yes, you can use LINQ to check if all items in that particular ObservableCollection<Bids> are OK

var areAllOK = source.All(x => IsValid(x));

You can get only these, which are valid:

var validItems = source.Where(x => x.IsValid(x));

or only these which are not valid:

var invalidItems = source.Where(x => !x.IsValid(x));

But you have to write IsValid method, and I cannot see how it could use LINQ internally.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
1

The bid values will need to be enumerable to perform a LINQ-based validation. Why not just make the bid values an observable collection as well? If you really have a good reason for each value to be a separate property, you could create the enumerable this way:

public IEnumerable<decimal> Values {
    get {
        yield return Bid1;
        yield return Bid2;
        yield return Bid3;
        yield return Bid4;
        yield return Bid5;
    }
}

For the validation, you would probably want a "sliding window". There is nothing included in LINQ for this, but some ideas are given in this answer. The easiest is to Zip {1, 2, 3...} with {2, 3, 4...}:

var pairs = Values.Zip(Values.Skip(1), (previous, current) => new {previous, current});

Then validate with All:

var isValid = pairs.All(p => p.previous != 0 && p.current >= p.previous);
Community
  • 1
  • 1
nmclean
  • 7,564
  • 2
  • 28
  • 37