1

We have a pretty extensive LINQ-to-SQL mapping with a back-end database containing around 150 tables. Almost all of the tables have a common property called CompanyCode which functions as a sort of partition across all of the tables.

I'm currently implementing a validation tool that makes use of context.GetTable<T> to retrieve records for a specific entity type. I want to filter by CompanyCode, but generically, e.g.:

context.GetTable<T>().Where(t => t.CompanyCode == "1234").ToList();

Since, we already have a custom abstract base class called CPSQLEntityBase, my thought was to add a custom virtual property CompanyCode that would be overridden in the LINQ classes as explained in this article:

public abstract class CPSQLEntityBase
{
    public virtual string CompanyCode { get; set; }
}

I am using a custom script that uses SqlMetal to dynamically generate our DataContext class. So it was trivial to add a command to find/replace all instances of public string CompanyCode with public override string CompanyCode so they would override the virtual property in the base class. Here is what one of them looks like for example:

public partial class Employee : CPSQLEntityBase, INotifyPropertyChanging, INotifyPropertyChanged
{
    ...
    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CompanyCode", DbType="VarChar(4) NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
    [global::System.Runtime.Serialization.DataMemberAttribute(Order=124)]
    public override string CompanyCode
    {
        get
        {
            return this._CompanyCode;
        }
        set
        {
            ...
        }
    }

    ...
}

Putting it all together, I wrote a little test script in LINQPad that should be able to request Employee entities using the generic method, but filtering by CompanyCode. Here is my sample script:

void Main()
{
    ...
    Test<Employee>(context);
}

public void Test<T>(MyDataContext context)
    where T : CPSQLEntityBase
{
    var result = context.GetTable<T>().Where(t => t.CompanyCode == "1234").ToList();
}

However, when I execute the code above, I get an exception:

Class member CPSQLEntityBase.CompanyCode is unmapped.

Has something changed since that Blog article was written? What am I missing?

mellamokb
  • 56,094
  • 12
  • 110
  • 136
  • Do you need to override it? Can't the property reside fully in the base class? – usr Jan 02 '13 at 19:39
  • @usr: That's what I tried first, and it gives the same error message. I also tried adding a `[Column]` Attribute directly to the base class property, and I get `Bad Storage property` exception, presumably because `CPSQLEntityBase` itself is not mapped to any entity in the SQL backend. – mellamokb Jan 02 '13 at 19:41
  • I found a duplicate that seems to answer my own question :) [**LINQ to SQL - mapping exception when using abstract base classes**](http://stackoverflow.com/questions/1021274/linq-to-sql-mapping-exception-when-using-abstract-base-classes). Looks like it may be a "bug" with a workaround. – mellamokb Jan 02 '13 at 19:46

0 Answers0