views:

61

answers:

2

Hi,

I'm getting a InvalidOperationException when trying to run this code:

database.Produkts.SingleOrDefault<Produkt>(x => x.Kod == "123")

It only occurs when the Kod property has an override modifier. I need it this way because the entity class is derived from another class that resides in a separate assembly.

Here's how the classes are defined:

The base class:

namespace Interfaces.Model
{
    [DataContract(Name = "Produkt", Namespace = "")]    
    public class Produkt
    {
        [DataMember]        
        public virtual string Kod { get; set; }

...

The class generated by Linq:

namespace DAL.Linq
{

  [Table(Name="dbo.Produkt")]
  public partial class Produkt : INotifyPropertyChanging, INotifyPropertyChanged
  {
        [Column(Storage="_Kod", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
        public override string Kod
        {
            get
            {
                return this._Kod;
            }
            set
            {
                if ((this._Kod != value))
                {
                    this.OnKodChanging(value);
                    this.SendPropertyChanging();
                    this._Kod = value;
                    this.SendPropertyChanged("Kod");
                    this.OnKodChanged();
                }
            }
        }
...

And the second part of the definition:

namespace DAL.Linq
{
    [DataContract(Name = "Produkt", Namespace = "")]    
    partial class Produkt : Interfaces.Model.Produkt
    {
    }
}

Now retrieving all the instances from the database (without the filter/where caluse) will work just fine. It's only that building a predicate that includes the overridden property will not.

I assume that it's some kind of a problem related to retrieving the property's attributes with reflection as the exception gets thrown from the method GetDataMember of the System.Data.Linq.Mapping.MetaType class.

My real question is if this is a Linq bug or can I somehow make Linq recognize this property to attribute mapping?

+1  A: 

All parts of the class should have the keyword partial.

Your code structure is really wierd, how do you even determine which implementation you are calling each time (if there are different implementations)?

Maybe you can make several classes that inherit Produkt instead of several partial parts of the class.

MrFox
Well, there are only two parts of the class DAL.Linq.Produkt (I omitted the namespace declaration in the second bit of code - added it now, sorry for that)Class Interfaces.Model.Produkt is the base class the DAL.Linq.Produkt class derives from.And my problem arises exactly because I am trying to do what you suggest, that is - using inheritance instead of making one class responsible for everything
Paweł Sokołowski
Class Interfaces.Model.Produkt is the base class the DAL.Linq.Produkt class derives from. That's not what you are doing here, because all three classes have the same class name!
MrFox
That's not true. They're in different namespaces. If I would be doing what you are suggesting I'd get a compilation error about duplicated class definition.Thanks for your effort but you're not really focusing on the problem here.
Paweł Sokołowski
A: 

Found a workaround here: http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/016ad28b-f813-4f26-9e70-2265a1943bad

In short: the query works after modifying it like this:

database.Produkts.SingleOrDefault<Produkt>(x => ((DAL.Linq.Produkt)x).Kod == "123")

The cast should be obsolete (and f.i. Resharper marks it as such) but evidently it does make a difference when reflection methods are applied to the resulting Expression objects.

Paweł Sokołowski