is one to one relationship bad strategy - c#

User always has one Wallet. One Wallet belongs always to one User.
Since I want to separate money wallet related properties I was create Wallet object and to be able to track money transactions, ... I created
public Wallet : Entity<int>
{
public double Amont {get; set;}
public IList<MoneyTrans> Transactions {get; set;}
}
Since this is obviously one to one relationship is it ok to map using one to one relationship?
Is one to one bad strategy?

I had to append answer, with opposite point of view. Do not use one-to-one mapping. At least with NHibernate.
I am not talking about the conceptual domain driven design. Just about my experience with DB design and NHibernate usage.
1) one-to-one - Rigid DB design
First of all the desing with shared primary keys (except of inheritance) could lead to many issues later, when the Business requirements are changed.
The typical scenario, very similar to example 23.2. Author/Work, where Author is mapped one-to-one to Person. Therefore, the id (primary key) of the Author comes from a Person (id). Sooner or later, Business will come and ask could we have to person mapped to Author (see Lars Kepler example)
What I am trying to say here is: Chapter 24. Best Practices (let me cite one point)
Declare identifier properties on persistent classes.
NHibernate makes identifier properties optional. There are all sorts of reasons why you should use them. We recommend that identifiers be 'synthetic' (generated, with no business meaning) and of a non-primitive type. For maximum flexibility, use Int64 or String.
As mentioned here (and from my experience), it is very benefitial to have all entities with their own surrogated primary keys. The changes in relations coming later - will effect just references (on top of surrogated keys), not the table/entities themselves.
2) one-to-one with NHibernate cannot be lazy
In fact this reason is the one, why (despite of the fact I tried few times) currently do not use the one-to-one at all. The one-to-one is not supporting lazy loading. Search for more info but nice explanation could be found here:
Ayende NHibernate one-to-one (a cite)
In other words, one-to-one cannot be lazily loaded, which is one of the reasons why it is recommended to use two many-to-one instead.
Some explanations on lazy loading (one-to-one)
As mentioned in one of the links in comments below the question (cite)
You can either include all those attributes as columns into your entity table - but in that case, lots of columns would end up empty for a significant number of the entries.
Or: you can put those "optional" attributes into a separate table, set up a 1:1 (or rather: 0:1) relationship with the base entity table,
Well, with NHiberante you won't get so much improvement. This suggestion is wrong. Lazy loading of one-to-one isn't supported...
SUMMARY:
That's why I would strongly suggest: use many-to-one or one-to-many where possible. You'll gain more...

No it's fine. It's not just about relationships but object orientation. Fundamentaly a Wallet is not an unseverable part of a Person.
Looking beyond that, whilst the wallet might belong to a specific 'John' now, 'James' might be given it as a present. From the data perspective it's much better to just change the WalletId fields of John and James of which one may be null (although not in your case) if they don't have a wallet.

Related

Orchard model inheritance with Table-Per-Concrete-Type?

I know that the underlying ORM used in Orchard is NHibernate and it does support the so-called ClassMapping which may help customize the mappings the way we want.
However I'm not sure about how Orchard utilizes the mapping methods supported by NHibernate. In this case it seems to always use the strategy similar to Table Per Type in EF as well as some other ORMs. With that strategy, the base class will be mapped to some common table whereas the derived class will be mapped to another table which contains all properties of its own (not declared in the base class). Those 2 tables will have a one-one relationship.
Now I really want to make it use the strategy similar to Table Per Concrete Type in which the base and derived classes will be mapped to 2 different tables with all properties (including inherited properties) being mapped to columns. Those 2 tables will not have any relationship, so querying for columns in just one table will not unexpectedly generate an inner JOIN (for one-one relationship).
Actually that requirement makes sense in case we just need to partition our data (from 1 big table to 2 or more small tables that have the same schema). We don't want to re-declare or use some kind of duplicate model classes (with different names), instead we just need to create a new model class and let it inherit from one base model class containing all necessary properties.
With the current code like this:
public class ARecord {
//properties ...
}
public class BRecord : ARecord {
//empty here
}
Currently we cannot use BRecord because it is understood as another part of the ARecord, the auto-generated query (always with INNER JOIN) will be failed because of some does-not-exist table or column names.
How can I solve this?
You're not going to like it ;) In a nutshell, the answer is don't do inheritance at all. Orchard was very deliberately designed around the idea of composition, steering well clear of inheritance in its content models. Maybe the central idea in Orchard is to make the concept of content part the "atom of content", and to design those basic units as very simple and composable pieces of functionality that do one thing well.
After all these years, the concept has held remarkably well, and I've yet to see an example of a content model where inheritance would have been more elegant and appropriate. This is reflected in the way nHibernate is customized and used in Orchard, as you've discovered.
So the solution to your problem can likely be one of two things:
You're modeling contents, and you should re-think your approach towards composition of parts. If you give a little more details about your specific scenario (maybe in a new question), I'm happy to help specifically in this direction.
You're modeling non-content data, in which case you might want to consider opting out of Orchard's specific nHibernate content-specialized idiosyncrasies and do things closer to the metal. Again, if you give more specifics about your scenario, I'm happy to take a look and give some pointers.

DDD with EF: Collection of Value objects

In a studied domain, a Car may have many Tires and according to DDD concepts, Car is an aggregate root while Tire is a Value Object. '
Consider the following model:
class Car
{
public int Id {get;set;}
public virtual ICollection<Tire> Tires {get;set;}
}
[ComplexType]
class Tier
{
public string Manufacturer {get;set;}
public int Diameter {get;set;}
}
I'm afraid EF 6.0 + cannot implement this model. Am I right? Any way to implement Collection of Value Objects?
Complex types, according to MSDN documentation, cannot participate in associations and cannot contain navigation properties so this is not the right way.
With EF the only way is to have 2 tables (with an Id on the Tires table). You can also hide Id of the Tires table, you can insert a unique index on the foreign key of the Cars table but when you check if two tires are equal you need to check if both properties are equal.
This is a common issue with normalized persistence (which includes the SQL server which you access through EF). Entity framework makes it more difficult by not allowing you to have a protected key though.
One way is to have a Tires table which has an id, which will form part of a foreign key relationship with car. However, the idea of a unique key violates the fact that value objects should not rely on id's and should be compared by value. Being diligent, overriding Equals, and only comparing by value will allow you work with this solution; it does not matter if the actual objects are different as long as the equality comparison would return true if two tires matched. It is not pretty, I agree, but with EF it seems to be the only solution. If I am wrong, please someone correct me. If you go this route, remember to map your domain data to your DTO's in a way that the Id is removed. That way you keep the fact that tires have an id isolated.
Another solution is to serialize the tires using Json before being sent to SQL db (and then deserialize it back on read), but that is not something that I would personally suggest if you need to query on information in the tires (for example give me all cars that use this kind of tyre).
PS: Vaughn Vernon discusses this particular issue with Hibernate for Java in this book: http://www.amazon.co.uk/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577 Please read, it will solve a lot of the issues or questions you may have on the subject.

EF DB-first mapping mess

I have a frustrating situation owing to this little quirk of EF. Here's a simple demo of the behavior. First the DB schema:
As you see, RestrictedProduct is a special case of product, which I'm intending to make a subclass of Product with some special code.
Now I import to an EF data model:
Oops! EF saw that RestrictedProduct had only 2 fields, both FKs, so it mapped it as a one-to-many relationship between Product and Restriction. So I go back to the database and add a Dummy field to RestrictedProduct, and now my EF model looks much better:
But that Dummy field is silly and pointless. Maybe I could delete it? I blow away the field from the DB table and the entity model, then refresh the model from the DB...
Oh, no! The Product-Restriction association is back, under a new name (RestrictedProduct1)! Plus, it won't compile:
Error 3034: Problem in mapping fragments starting at lines (x, y) :Two entities with possibly different keys are mapped to the same row. Ensure these two mapping fragments map both ends of the AssociationSet to the corresponding columns.
Is there any way to prevent this behavior, short of keeping the Dummy field on the RestrictedProduct table?
I just came across the same issue, and as an alternative to putting the dummy field in your RestrictedProduct table to force the creation of an entity you can also make your RestrictedProduct.RestrictionId field nullable and EF will then generate an entity for it. You can then modify it to use inheritance and any subsequent "Update model from database" will not cause undesired nav properties. Not really a nice solution but a work around.
Let's walk slowly into your problem.
1st thing you need to decide is if the restricted product is
really a special case of product or is it a possible extension
to each product.
From your original DB Scheme it seems that any product may have
a relation to a single restriction however a single restriction
can be shared among many products.. so this is a simple 1 to many
situation which means that restricted product is NOT a special case
of product! Restriction is an independent entity which has nothing
to do with product in a specific way.
Therefore EF is correct in the 1st importation of your scheme:
1. a product can have 0 or 1 restrictions.
2. a restriction is another entity which can be related to many products.
I do not see your problem.

Entity Framework - making a large edmx table more manageable by splitting?

I think this is a question of the best technique or best way to skin a cat!
Imagine a menu with items (menu choices) on it. I have a table called MenuItem, which for example "Spaghetti Bolognese", it has lots of other information associated with it aside from just a better description and picture.
Eg.
Basic Information (Name, Description, Picture, etc)
Nutritional Information (approx 15 columns)
Allergy Information (approx 16 columns)
Dietary Information (another 7 columns) (religious etc)
As it is at the moment I have it all in the one table in SQL server, which is logical database design to me as it doesn't repeat, despite it making the field list for the table longer than I would like. I'd already been feeling a bit bad about just continually extending the database table. But now we also want to add 'Recipe' information, approx another 7 columns.
I'm using Entity Framework 4.latest, and feel there is probably functionality to help me split this off within the EDMX? (Is that what ComplexTypes are?) Or do I just need to do this in the ViewModel class I call?
I think what I'm after using in my code to segregate things better is something like
MenuItem.Recipe.Ingredients
MenuItem.Nutrition.Fat
etc
Complex types can help you but be aware that complex types cannot contain navigation properties, cannot be null and are always loaded with the entity. Other possibility is to use table splitting - this will allow you to map multiple one-to-one related entities to the same table. The main features of table splitting are:
Entities can share only primary key properties
There is one main entity and others are considered as relations (navigation properties)
Related entities must exists - they are not optional so when you insert new main entity you must insert these related entities as well even if they are empty
Related entities must be loaded with eager, lazy or explicit loading

Abstract Base class for All Domain Entity Objects

I am seeing in some domain object models that an abstract base class is created(that implement Equals and GetHashCode) for all domain Entity objects to inherit from to gain their identity.
I am not clear why this base class is needed and when and why it should be used. Can you provide me some insight on this or refer me a link that talks on this
Thanks
Now I understand the advantages of overriding Equality (this link helped http://en.csharp-online.net/CSharp_Canonical_Forms—Identity_Equality)
Going back to domain driven design I would like to expand my question a bit;
I have a customer entity which I use guid as identity.
If I create 2 instances of customer with exactly the same details, since I am using guid as the identity they will be two different objects. But as they have all attributes the same they should be the same object(or is it a better ddd practice to keep them unique and seperate??)
Trying to understand if I should handle the equality of two objects by their full attribute value match. If I go toward that direction then I am looking at either overriding the Equality of the base class on the level of sub class and implement these conditions or have the identity of the entity a string or hash code(?) representation of the values of all these attributes and use the Equality of the base class.
I could be little off here so thanks in advance for the patience.
The use of the term equality is overloaded here:
1) Equality for Identity
If you have 2 instances of the same Customer, they should both have the same GUID value – it’s the only way to ensure that you're working with the same Entity. In reality, there will always be different instances of the same Entity (e.g. multi-user apps running on different machines).
2) Equality for sameness
This is where you're checking that 2 instances have all the same values. For instance, if 2 staff members are looking at the same Customer, and the first person modifies & saves it, both people will see different data. They’re both interested in the same Customer, but the data becomes stale.
For (2), you definitely need a mechanism to do the checking. You could compare each property (expensive), or you could use a ‘version’ property to detect changes (see NHibernate’s optimistic locking mechanism).
I think your example is a bit contrived, and might be drawing you away from the more important aspects of DDD. If you’re interested, I sell a tool that can help grasp DDD concepts easier.
You should compare the IDs of the objects if they are entities and their attributes in case they are value objects. That means that you don't have to inherit your value objects from a base entity, but for entities it's better to create one.
How to understand if a class is an entity or a value object? You should answer a question: are objects of such class equal if they have the same attribute set? If yes, they are values objects. For example, two persons are not equal even if they have the same names and birth dates - you should treat them as different entities anyway. But if you have 25 cent coin, you probably don't care what exact piece of metal do you have, they all just 25 cent coins.
There's a great article describing the details: domain object base class
If you are following DDD, I believe you should check on the equality of the objects by their ID (Identity). This is because domain entities are primary defined and tracked by its identity and not by attributes. So no matter how similar they are with other objects, they are still diffirent entities.
Another concept that you would want to check out is a value object. It is something that describes a charasteristics of an object and doesn't require an identity. Example would be, address, money, color.
You pointed at two of the reasons of why it is used.
For Equals you may not want to always check if the actual reference is equal, because it may not be. You may want to use some sort of identifying property (like public int ID) to check against to see if 2 entities are equal. The base implementation of Equals is just going to check if the 2 references are equal.
As far as hash code it's a way to uniquely identify a given object/type when using it in hash algorithms etc.
I would have equals only check on identity, because it allows you to have an instance of an entity containing a before and after situation, which can be very handy at times. To check if an instance has changed, a Dirty flag can do the trick.
HTH,
Jonathan

Categories

Resources