Linq to Sql inheritance mapping to multiple tables - linq-to-sql

I am having trouble with inheritance mapping in Linq to Sql. I am using MSDN as a reference and as a basis it sounds good. However the example it gives is a single table inheritance mapping. However, I am trying to do multiple table inheritance to save on table space. Is this possible? So far I have:
[Table(Name="writing_objs")]
[InheritanceMapping(Code="T",Type=typeof(ObjectTypeA), IsDefault=true)] // Only default because a default is required
[InheritanceMapping(Code="N",Type=typeof(ObjectTypeb))]
public abstract class WritingObject
{
/* ... */
[Column(Name="obj_tp", IsDiscriminator=true)]
[StringLength(1)]
public string ObjectType { get; set; }
}
I then have the different object types defined like so:
[Table(Name="obj_type_a")]
public class ObjectTypeA: WritingObject
{
/* Object Type A fields */
}
The issue seems to be that I am defining a table attribute in the 2nd type, as I get the following exception:
The inheritance subtype 'ObjectTypeA' is also declared as a root type.
Is it possible to keep these fields in separate tables with Linq to Sql or am I going to have to consolidate them all into a single table? Is it necessarily bad to have some extra fields in one table as long as there aren't too many (some object types might even be able to share some fields)?

Linq to SQL does not support multiple-table inheritance using a discriminator, even though that is the best design in many cases (it's the most normalized).
You'll have to implement it using associations instead. If you use a mapping layer that converts it to an inheritance-based domain model, it will be easier to manage at higher layers.

Well I know this problem has already been resolved, but as I just encountered the same issue, I'd like to share what I did :
Just remove the [Table] attribute from your inherited classes. And it's quite logical, because we define in the generic classes a way to store all subtypes (with the discriminatory attrbute).
Maybe this will help someone in the future.

Related

Grails: Where do I handle a domain class property that can have two different representations?

I am programming a way of displaying products that I get from a MySQL database based on user input. My products have a property (size) that can either be represented by a string, by an object of the type Size (another domain class holding three float-values) or be missing alltogether.
Currently my Product-Class has one property for each representation, both of which are nullable. In my view I have one specific place where this property should be displayed.
Now my question is, where do I handle the problem of determining which representation I have for a specific object?
I would be able to include an if-condition in my gsp-template but that seems to be bad practice.
I would be able to have the service that does the query handle the results and build a single size-property to pass to the template but that doesn't seem right either.
Is the problem in my database design?
Do I have to change my domain-model?
I am sorry for the very general question, I can definitely change that once I know where exactly I need to change something. Thanks a lot already!
One way to solve your problem would be to use an additional transient field that would be used in your views, but would not be persisted in your database.
class Product {
String sizeString
Size sizeSize
getSize() { sizeString ?: sizeSize.toString() }
static transients = ['size']
}

Using RIO and Sqlite-net in MvvmCross

In the excellent mvvmcross-library I can use RIO binding to prevent unreadable code:
public INC<String>Title = new NC<String>();
Then I can read and write values using Title.Value. Makes the models much more readable.
Normally, this property would be written as:
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
RaisePropertyChanged("Title");
}
}
But when I want to use sqlite-net, these fields cannot be streamed to the database because they are not basic types with a getter and setter.
I can think of a few options how to get around that:
Make a new simple object that is similar to the model, but only with
the direct db-fields. And create a simple import-export static
method on the model. This also could prevent struggling with complex
model-code that never needs to relate to the actual database.
Make sqlite-net understand reading NC-fields. I read into the code of the mapper, but it looks like this is going to be a lot of work because it relies on the getter-setter. I did not find a way to insert custom mapping to a type, that could be generic.
Remove RIO and just put in all the code myself instead of relying on RIO.
Maybe someone has some advice?
Thanks Stuart. It was exactly my thought, so I did implement it that way: my (DB) Models do not contain RIO. Only my viewmodels do, and they reference a Model that is DB-compatible.
So, for posterity the following tips:
- Do not use RIO in your models that need to be database-backed.
- Reference models in your viewmodels. In the binding you can use the . (dot) to reference this model.
This keeps them nicely separated. This gives you also another advantage: if you need to reuse a model (because the same object might be displayed twice on the screen), but under different circumstances, it is much easier to handle this situaties to find this already instantiated model.

Polymorphic belongsTo in many to many mapping in grails?

So i know this is possible using a superclass, however, this is very limiting in flexibility. So my question is then, can i use an interface? Something ala.
interface Taggable {
/*Adds tag(s) and returns a list of currently set tags*/
List<String> addTags(String ... tag)
/*Removes tag(s) and returns a list of currently set tags*/
List<String> removeTags(String ... tag)
}
class User implements Taggable {
String username
static hasMany = [tags:Tag]
}
class Tag {
String name
static hasMany = [references:Taggable]
static belongsTo = Taggable
static constraints = {
name(nullable: false, blank: false, unique: true)
}
}
Im interested in a reference back to the object who has the following tag. This object however can't extend a concrete class. Thats why im wondering if this can be done with an interface instead.
So, can it be done?
Hibernate can map an interface - see example. I doubt if Grails supports this in by-convention mapping - but you can try using the mapping annotations from example above, or XML config.
edit: answering a comment question:
On a database level, you have to have a Taggable table for Tag.References to reference with a foreign key.
Discriminator will NOT defeat polymorphism, if it's added automatically - for instance, in table-per-hierarchy mapping, Hibernate/Gorm adds a class field in order to find out a concrete class when reading object from db.
If you map your Taggables to two tables - Taggable part to Taggable and everything else to specific table, referenced 1:1 - all the discriminator work should be done for you by Hibernate.
BTW class field is pretty long - it contains fully qualified class name.
edit 2:
Either way, it's getting pretty complex, and I'd personally go with the approach I suggested in another question:
dynamically query all the classes with Taggable interface for hasMany=[tags:Tag] property;
or, less preferable - to have a hand-crafted child table and a discriminator.

Will manual Linq-To-Sql mapping with Expressions work?

I have this problem:
The Vehicle type derives from the EntityObject type which has the property "ID".
I think i get why L2S can't translate this into SQL- it does not know that the WHERE clause should include WHERE VehicleId == value. VehicleId btw is the PK on the table, whereas the property in the object model, as above, is "ID".
Can I even win on this with an Expression tree? Because it seems easy enough to create an Expression to pass to the SingleOrDefault method but will L2S still fail to translate it?
I'm trying to be DDD friendly so I don't want to decorate my domain model objects with ColumnAttributes etc. I am happy however to customize my L2S dbml file and add Expression helpers/whatever in my "data layer" in the hope of keeping this ORM-business far from my domain model.
Update:
I'm not using the object initialization syntax in my select statement. Like this:
private IQueryable<Vehicle> Vehicles()
{
return from vehicle in _dc
select new Vehicle() { ID = vehicle.VehicleId };
}
I'm actually using a constructor and from what I've read this will cause the above problem. This is what I'm doing:
private IQueryable<Vehicle> Vehicles()
{
return from vehicle in _dc
select new Vehicle(vehicle.VehicleId);
}
I understand that L2S can't translate the expression tree from the screen grab above because it does not know the mappings which it would usually infer from the object initialization syntax. How can I get around this? Do I need to build a Expression with the attribute bindings?
I have decided that this is not possible from further experience.
L2S simply can not create the correct WHERE clause when a parameterized ctor is used in the mapping projection. It's the initializer syntax in conventional L2S mapping projections which gives L2S the context it needs.
Short answer - use NHibernate.
Short answer: Don't.
I once tried to apply the IQueryable<.IEntity> to Linq2Sql. I got burned bad.
As you said. L2S (and EF too in this regard) doesn't know that ID is mapped to the column VehicleId. You could get around this by refactoring your Vehicle.ID to Vehicle.VehicleID. (Yes, they work if they are the same name). However I still don't recommend it.
Use L2S with the object it provided. Masking an extra layer over it while working with IQueryable ... is bad IMO (from my experience).
Otherway is to do .ToList() after you have done the select statement. This loads all the vehicles into your memory. Then you do the .Where statment against Linq 2 Object collections. Ofcourse this won't be as effecient as L2S handles all of the query and causes larger memory usage.
Long story short. Don't use Sql IQueryable with any object other than the ones it was originally designed for. It just doesn't work (well).

applying separation of concerns

I wonder if you think that there is a need to refactor this class.( regarding separation of concern)
publi class CSVLIstMapping<T>
{
void ReadMappingFromAttirbutes();
void GetDataFromList();
}
ReadMappingFromAttributes - Reads the mapping from the type T and stores it in the class. Has a name of the list to use and a number of csvMappingColumns which contains the name of the property to set the value in and the name of csvcolumns.
GetObjectsFromList - uses a CVSListreader ( which is passed in via the constructor) to get the data from all row's as KeyValuePair ( Key = csvcolumnName , value = actually value) and after that it uses the mappinginformation( listname and csvMappingColumns ) to set the data in the object.
I cant decide if this class has 2 concerns or one. First I felt that it had two and started to refactor out the conversion from rows to object to another object. But after this it felt awkward to use the functionality, as I first had to create a mappingretriver, and after that I had to retrive the rows and pass it in together with the mapping to the "mapper" to convert the objects from the rows
/w
Sounds like two concerns to me: parsing and mapping/binding. I'd separate them. CSV parsing should be a well-defined problem. And you should care about more than mere mapping. What about validation? If you parse a date string, don't you want to make sure that it's valid before you bind it to an object attribute? I think you should.
Rule of thumb: if it's awkward, it's wrong.
I have to say I'm finding it hard to understand what you've written there, but I think it's likely that you need to refactor the class: the names seem unclear, any method called GetFoo() should really not be returning void, and it may be possible that the whole ReadMappingFromAttribute should just be constructor logic.