I'm usign inheritance in linq2sql and have entites Supplier and Buyer that inherits from Client. I need to be able "upgrade" a Buyer to a Supplier.
I've tried:
Client client = ClientMethods.ValidateId<Client>(clientId);
client.ClientTypeId = ClientMethods.CLIENT_TYPE_SUPPLIER;
db.SubmitChanges();
But get "Not allowed: Inheritance discriminator change from '1' to '2' would change type from 'Buyer' to 'Supplier'."
The only solution I can find is to do this without linq2sql and write a SP??
I am wondering why you even have the two different sub classes if it is a natural situation that you want to change from one type to the other. I think that you should refactor what you have and make the buyer and supplier one entity. Then if you have behavior that should be different based on whether or not the client is a buyer or supplier I would extract that into a seperate object which you can set or add to the client.
i just had the same problem, and solved*) it by doubling the discriminator field into one computed column that is actually used as discriminator value and an integer column storing the value ...
*) - one of the famous solutions that could have nasty side effects, so be warned
Perhaps, try to create a new supplier by populating the buyer's properties' value?
Related
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.
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.
According to REST philosophy, a PUT operation should (taken from Wikipedia):
PUT http://example.com/resources/142
Update the address member of the collection, or if it doesn't exist, create it.
NHibernate seems to have two ways of dealing with entity IDs:
Auto-generate an ID, regardless of what value the user set.
Use the ID assigned by the user, but lose all auto-generation capabilities.
The problem here with a PUT operation is the part about creating the entity if it doesn't exist. My assumption is that if you PUT a resource that doesn't exist, it will create it with the same ID as specified by the URL (such as 142 if we use the above example). However, NHibernate doesn't allow you to set the ID if it's auto-generated.
So my question is, is there a way to get NHibernate to auto-generate an ID if the entity doesn't have one (or has the default value for the ID type, for example 0 for ints), but also save the entity with the ID that the user set?
Generally its a bad idea to use assigned ids.
The situation that you have is closer to the thing called NaturalId. You should use it I think. You will need to have two different properties, one for databases primary key, and second as a id that is visible to users.
I'm thinking of building a ecommerce application with an extensible data model using NHibernate and Fluent NHibernate. By having an extensible data model, I have the ability to define a Product entity, and allow a user in the application to extend it with new fields/properties with different data types including custom data types.
Example:
Product can have an addition fields like:
Size - int
Color - string
Price - decimal
Collection of ColoredImage - name, image (e.g. "Red", red.jpg (binary file))
An additional requirement is to be able to filter the products by these additional/extended fields. How should I implement this?
Thanks in advance.
I think this link describes kind of what you want...
http://ayende.com/Blog/archive/2009/04/11/nhibernate-mapping-ltdynamic-componentgt.aspx
More info on dynamic-component:
http://www.mattfreeman.co.uk/2009/01/nhibernate-mapping-with-dynamic-component/
http://bartreyserhove.blogspot.com/2008/02/dynamic-domain-mode-using-nhibernate.html
The idea behind dynamic-component is that you can build your data model by not having a one to one mapping of databse columns with properties. Instead you have only a dictionary property that can contain data from as many properties as you like. This way when you fetch the entity, the dictionary gets the data of all columns configured to belong in there. You can extend the database table's schema to include more columns and that will be reflected to the databse model if you update the mapping file accordingly (manually or though code at application start).
To be honest I do not know you can query such entity using the "attributes" property but if I had to guess I would do an IN statement to it.
One of the options is EAV model (Entity-Attribute-Value).
This model is good to apply if you have a single class in your domain, which table representation would result in a wide table (large number of columns, many null values)
It's originally designed for medical domain, where objects may have thousands of columns (sympthoms).
Basically you have
Entity (Id) (for example your Product table)
Attribute(Id, ColumnName)
Value(EntityId, AttributeId, value)
You can have some additional metadata tables.
Value should better be multiple tables, one for a type.
For example:
ShortStringValue(EntityId, AttributeId, Value nvarchar(50));
LongStringValue(EntityId, AttributeId, Value nvarchar(2048));
MemoValue(EntityId, AttributeId, Value nvarchar(max));
IntValue(EntityId, AttributeId, Value int);
or even a comple type:
ColorComponentsValue(EntityId, AttributeId, R int, G int, B int );
One of the things from my experience is that you should not have EAV for everything. Just have EAV for a single class, Product for example.
If you have to use extensibility for different base classes, let it be a separate set of EAV tables.
Onother thing is that you have to invent a smart materialization strategy for your objects.
Do not pivot these values to a wide row set, pivot just a small number of collumns for your query criteria needs, then return a narrow collection of Value rows for each of the selected objects. Otherwise pivoting would involve massive join.
There are some points to consider:
. Each value takes storage space for foreign keys
. For example row-level locking will behave different for such queries, which may result in performance degradation.
. May result in larger index sizes.
Actually in a shallow hellow world test my EAV solution outperformed it's static counterpart on a 20 column table in a query with 4 columns involved in criteria.
Possible option would be to store all extra fields in an XML structure and use XPath/XQuery to retrieve them from the database.
Each extensible entity in your application will have an XML field, like ExtendedData, which will contain all extra properties.
Another option is to use Non-relationnal Databases which are typically suited for this kind of things.
NOSQL databases(couchDB, mongoDB, cassandre...) let you define dynamically your propretyfields, you could add fields to your product class whenever you want.
I'm searching for similar thing and just found N2 CMS (http://n2cms.com) which implements domain extensibility in quite usable way. It also supports querying over extension fields which is important. The only downside I find out is that it's implemented using HQL so it would take some time to reimplement it to be able to query using QueryOver/Linq, but the main idea and mappings are there. Take a look on ContentItem, DetailCollection, ContentDetail classes, their mappings and QueryBuilder/DetailCriteria.
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