1

I've implemented a content management system that deals with a certain kind of object, and now the client has introduced another kind of object, whose structure and behavior is exactly the same, but separate. They want to be able to switch modes, where each mode behaves identically, except that one deals with one object type and the other with the other.

Suppose the first object type is stored in a table called TBL_OBJECT, and the second in one called TBL_OBJECT_NEW. I'm looking for a way to use my existing code, but to be able to switch on the fly and have it switch to the other table. Because the structure is identical, this is conceptually possible. The only problem is that in L2E, the table name is saved as attribute and compiled in, so I'm looking for a way to hook the sql statement creation process, so that my existing statements like this:

Dim db as New DataContext
Dim query = From obj in db.Objects

will resolve to the TBL_OBJECT_NEW table instead of the TBL_OBJECT table. If I can do this, I can reuse a huge amount of code. I know it's a somewhat unusual scenario, but I'm really hoping it's possible. Any help much appreciated! Thanks.

By the way, I'm using LinqConnect from DevArt for this; I don't know how much a plain L2E approach will apply to this. On the other hand, if you know how to do it with DevArt but NOT L2E, that would still be very helpful.

Joshua Frank
  • 13,120
  • 11
  • 46
  • 95

1 Answers1

1

We are not aware of any possibility of having two identical tables mapped to one conceptual entity.

Both in LinqConnect and in Entity Framework there is a solution. For example, you can try switching between two models having only one difference (the first model will map TBL_OBJECT, the second - TBK_OBJECT_NEW).

LinqConnect solution:

To switch between different tables with the same structure in LinqConnect, you can create two .lqml files and load mapping from one of them for the current DataContext instance:

string mappingFileName;
if (...) // Check whether TBL_OBJECT_A should be used
  mappingFileName = "MyDataContext_A.lqml";
else 
  mappingFileName = "MyDataContext_B.lqml";
Stream contextStream = System.IO.File.OpenRead(mappingFileName);
System.Data.Linq.Mapping.MappingSource mappingSource =
Devart.Data.Linq.Mapping.XmlMappingSource.FromStream(contextStream);
MyDataContext context = new MyDataContext(connectionString, mappingSource);

Also, we plan to support fluent mapping (the approach when mapping is set in your code without using attributes or mapping files), though cannot provide any timeframe for this at the moment. You can vote for this feature at our UserVoice.

Entity Framework solution:

Set the Metadata Artifact Processing property to CopyToOutputDirectory. After this go to the generated SSDL files and change the table name from "TBL_OBJECT" to "TBL_OBJECT_NEW". The only thing now is to create the context with the correct connection string (you can either add a new connection string to the application configuration file or pass the entire connection string to the ObjectContext constructor).

Devart
  • 119,203
  • 23
  • 166
  • 186
  • This worked for me, although I did run into a curious problem where the code started giving an error "Provider type not found", where it hadn't before. I was able to fix this by setting CopyLocal to True on the DevArt dll's. Not sure why it was not able to find them in the GAC using this approach, but could using the other. I also found it more convenient to keep one copy of the lqml file and flip the table names on the fly, rather than keeping two separate copies. Anyway, I was very glad that I was able to do what I needed relatively simply. Thanks. – Joshua Frank Feb 15 '11 at 13:43