Jamie Twells
Jamie Twells

Reputation: 2144

Unable to assign to object property after getting from database

I have this class:

public class Product {
    [NotMapped]
    public bool Recommended {get;set;}

    public int ID {get;set;}
    //Other stuff
}

Then I get them from the database and assign the Recommended variable. I've set them all to true for now, while I test and that works.

var Products = Find(SearchParams, DataContext).ToList();
foreach(var product in Products) {
    product.Recommended = true;
    if (!product.Recommended) throw new Exception();
}

Ok, it works, we pass.

Then I go and make a set of results, which look like this:

public class QuoteProduct {
    public Product Product {get;set;}
    public Quote Quote {get;set;}
    //etc
}

And assign the products:

var Results = new List<QuoteProduct>();
foreach(var product in Products) {
    var entry = new QuoteProduct(){
        Product = product;
        Quote = getQuote(this);
    }
    if (!entry.Product.Recommended) throw new Exception();
    Results.add(entry);
}

and that exception is always thrown! Why? Even if, just before it I do:

    entry.Product.Recommended = true;
    if (!entry.Product.Reccomended) throw new Exception();

Upvotes: 1

Views: 54

Answers (1)

Jeroen van Langen
Jeroen van Langen

Reputation: 22073

Lazy evaluation problem

Find(SearchParams, DataContext); is probably returning an IEnumerable<> so each time you iterate it, new Product classes are generated. This makes the product.Recommended = true; useless.


Here:

var Products = Find(SearchParams, DataContext);
foreach(var product in Products)    // <--- here it's iterated and new classes instantiated
{
    product.Recommended = true;
    if (!product.Recommended) throw new Exception();
}

and here:

var Results = new List<QuoteProduct>();
foreach(var product in Products)   // <-- and here are new classes instantiated
// So your previous `product.Recommended = true;` is gone!
{
    var entry = new QuoteProduct(){
        Product = product;
        Quote = getQuote(this);
    }
    if (!entry.Product.Recommended) throw new Exception();
    Results.add(entry);
}

You can fix it with:

// The key is to persist the data with (for example) ToArray() or ToList()
var Products = Find(SearchParams, DataContext).ToArray();

The downside of persisting is, that ALL 'rows' are loaded simultaneous into the memory. (that's why the lazy evaluation is usefull)

Upvotes: 2

Related Questions