1

I asked the question this way because I can imagine that there's a potentially easy but Devart specific solution, but maybe also a very general solution for any similar situation.

I'm using Devart LINQ To Oracle, and generally you create a class like ItemX in the lqml file at design time and specify what table is behind it. Then, at run time, you use a Table(Of ItemX) to query the database. So far so good.

Now I've got a situation where I have two identical tables, ItemX and ItemY, and I need to query from one or the other depending on a runtime flag. Other than this, all code is identical and I want to keep it that way. However, the Table(Of ItemX) is strongly typed, and so I would need to have duplicate versions of everything, with the only difference being the data type.

So, the Devart specific solution would be: have one item class called, just, Item, but at runtime do something so that the Devart DataContext uses a different backing table. Then all code uses the base Item object, but when persisting to and from the database, it knows which table to use. Is there any way to do this?

The more general approach would be some way of hooking into the IQueryable chain so that it used the ItemX and ItemY classes internally, but transformed everything to the base Item class in the external signatures. I can't even picture this clearly enough to phrase the question though. Is there any way to accomplish this?

Joshua Frank
  • 13,120
  • 11
  • 46
  • 95
  • Why do you have two tables then, if their contents are interchangeable, both in type and meaning? – Lasse V. Karlsen Feb 08 '12 at 13:24
  • There are two kinds of documents that I have to track, and the data structures and logic for each kind are identical, but sometimes they want to see a list of type X and sometimes type Y. you may be thinking there should be one table with a DocumentType column to keep the document types separate, and you may be right. However, it was done this way long ago, when two similar systems merged, and renormalizing in this way now would be very, very messy. – Joshua Frank Feb 08 '12 at 13:43

1 Answers1

1

You can implement this scenario by manually creating a base class (which is not mapped to any table) and two its 'trivial' descendants (each mapped to one of the tables you work with).

More precisely, the following steps should be performed:

  • generate a model with an entity class corresponding to either of the tables;
  • move this entity class from the generated code somewhere else;
  • remove the Table attribute from this class;
  • (optionally) rename the class to, e.g., 'ItemBase';
  • declare two public descendants of this class (e.g., 'ItemX' and 'ItemY');
  • set the Table attribute pointing to the proper table on each of these descendants;
  • remove the 'ItemBases' property (the one returning a Devart.Data.Linq.Table object; of course, it may have some other name) of your DataContext class and add analogous properties returning Table and Table instead.

Thus, this should look like

namespace MyContext {

  public partial class ItemBase : INotifyPropertyChanging, INotifyPropertyChanged {
    ... // Generated code.
  }

  [Table(Name = @"ItemXs")]
  public partial class ItemX : ItemBase {}

  [Table(Name = @"ItemYs")]
  public partial class ItemY : ItemBase {}

  public partial class MyDataContext {

    public Devart.Data.Linq.Table<ItemX > ItemXs {
      get { return this.GetTable<ItemX>(); }
    }

    public Devart.Data.Linq.Table<ItemY> ItemYs {
      get { return this.GetTable<ItemY>(); }
    }
  }

}
Devart
  • 119,203
  • 23
  • 166
  • 186