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
Related
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.
I have a question about about proxy in NHibernate. I've inside in my log file a lot of logs like: Narrowing proxy to - this operation breaks ==
There are a few other questions on the web and different answer:
Stackoverflow NHibernate narrowing proxy warning It being a big deal or not depends on the level of risk you are willing to accept. Since there is going to always been a disconnect between your code and your database you can not always assure that the casting will work. This will lead to bugs that might be difficult to diagnose and may not be resolved without changes to the database or the code.
Another post from hibernate:
Narrowing problem Don't worry about his warning, just put the following in your log file and you shouldn't see it anymore...
Why it happens?
Suppose you have a Product with a many-to-one association to Address. Both are entities and Address has a ShippingAddress subclass.
Let's Session.get(..) a Product from the db that has ShippingAddress as association. Because the many-to-one is lazy, it will return a Address proxy. Note that this is a Address proxy and not a ShippingAddress proxy as the proxy will always match the type that is mentioned in Product (see the hibernate book for details).
This proxy is stored by Hibernate in his proxy cache.
Now we Session.get(...) the same ShippingAddress from the db, the one that is associated to the Product that we used fetched from the db.
Now Hibernate will see that it already contains a proxy for this ShippingAddress and will return this. However, it will notice that the types aren't the same so a "downcasting" must occur. Because this latter action isn't possible with "proxies" it will create new one and return it...
As you can see, nothing to worry about.
You could consider making the Address a value type...
In my case that's no option.
And a last one
ProxyWarnLog Removed in Hibernate 4?
Here is the code from NHibernate: StatefulPersistenceContext.cs -> NarrowProxy(..)
So, is it a problem or not? I always work with detached objects in my program.
I hope someone can help me.
Thanks a lot.
This can be a trouble if you use the == operator to compare entities and decide whether they are the same one or not.
This does similarly occur (but with Equals indeed) when you add an entity to a collection mapped as a set. If the set happens to already contain the entity but instantiated through another proxy type, the add may fail to respect its contract, it may add again the entity, and the set would then contains two occurrences of the same entity.
This is a may, not a will, because you can avoid this trouble by overriding Equals (and GetHashcode, as it is mandatory to return the same hashcode for objects being equal) on your entities, in order to compare them through their primary key and entity type. For set, it is sufficient (since it do not use the == operator, but the Equals method, prioritizing the one from IEquatable<T> if your type implements it).
For ==, you need then to define the == and != operators on your class for using your Equals implementation.
Read here or here for more on this. Beware, their example implementations are just examples, and are not suitable for a domain model using inheritance. Read here for a overriding example handling inheritance. (But it does not handle transient entities: better append to it a final test on natural ids if they have one, rather than yielding false if both are considered transient while being not the same reference.) And this blog provides a base class with == redefined (found in this Stack Overflow question).
Working with detached entities increases this risk. If you have not already overridden those two methods on your entities, it would be safer to do it, regardless of this warning.
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.
I have a Candidate class. When somebody deletes a Candidate, I want a DeletedCandidate which is derived from Candidate to be stored in a separate table.
How can I model this in EF, Code first? I think my best option is TBC, but when I use the following in Context, a System.Data.MappingException is thrown.
modelBuilder.Entity<DeletedCandidate>().Map(d => {
d.ToTable("DeletedCandidate");
d.MapInheritedProperties();
});
I would not use inheritance for archiving-like tasks. You will always have to make a distinction between Candidates and DeletedCandidates in your mainstream application code. With EF you'll have to do that by always retrieving candidates by OfType<Candidate>.
I would make a separate class (and table) for DeletedCandidates. Thus, you can always get to them when needed, but they never get in harm's way in the rest of your code. A drawback may be that you always have to keep the properties (and columns) of the two in sync. This could be relieved by having both classes implement a common interface (which you can easily do with code-first).
If you need to preserve foreign key relationships to DeletedCandidates it's a different story. In that case I think the best you can do is using a deleted flag (but you're going to need filtering to get the active candidates).
Just an advice :D.
I've found one that allows multiple fields of type long. However, i'm not sure how useful that is since sometimes we may have Guids or even dates for example.
I could also modify his to support my needs, but this seems like it would be such a common request that I should be able to find something tested, tried and true instead of creating it from scratch.
The main purpose i have behind this is use the Identity Map pattern. I believe this pattern more or less requires the Identity Field pattern to support it. I will use the Identity Field construct as the key to my dictionary
Any ideas?
Thanks
I think to implement a similar pattern for a multi-column PK, you would just need to create a field/property on your class for each of the PK columns on the table.
For example, if you had a "Message" table with a PK with a long, a guid, and a datetime, your class would just need to include a long, Guid, and a DateTime property.
You would probably also want to implement Equals() and GetHashCode() for the object using these PK fields, because you want these objects to compare in database terms, not in terms of the in-memory address of the object. GetHashCode is important, because you want to ensure that Objects with the same PK properties produce the same hash code. To implement GetHashCode, I would recommend looking at Jon Skeet's answer here: What is the best algorithm for an overridden System.Object.GetHashCode?
Fowler's "Identity Field" pattern maybe assuming that your tables have a single surrogate PK column, and that is why he specifies it the way he does.
Check out S#arp Architecture. When you inherit from their Entity object, you can decorate as many properties as you want to with the DomainSignatureAttribute. These properties will then be considered as the object's identity in the implementation of Equals and GetHashCode that is provided in Entity.