I'm trying to map two domain entities to the same table. We're doing a smart entity for our domain model, so we have the concept of an Editable Address and a readonly Address. I have both mapped using Classmaps, and everything seems to go fine until we try to export the schema using the SchemaExport class from NHibernate. It errors out saying the table already exists.
I assume it's something simple that I'm just not seeing.
Any ideas?
Thanks
Update
There are a couple of other things I didn't mention which I should have. I appreicate those that answered so far, but they don't work for us.
One is that we have a single address table, not include the columns in whatever entities have an address.
The other is that we can't use a common base class. For editable objects, we have a super class which adds validation behaviors to the subclasses. The readonly objects don't need this behavior though and should not have these behaviors.
I have considered an interface, but then I believe I end up in a situtation where you can cast a readonly object to this interface and then changes its values (since presumably NHibernate would use said interface to hydrate the object).
So if there's another way to acomplish this, or if mapping via an interface won't have the problem I described, please let me know. I'm still learning NHibernate.
Thanks again!
you can Exclude the readonly class from schemaexport:
public class ReadonlyAdressMap : ClassMap<ReadonlyAdress>
{
ReadonlyAdressMap()
{
Schemaaction.None();
[...]
}
}
Create one base abstract class entity which you will later extend to the Editable Address and the ReadOnly Address.
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 created an entity data model and generated a database from it.
One of the entities is called Template.
Created partial classes to extend the functionality of Template works fine.
If I create a new class and try to derive from Template, I get a runtime exception upon instantiating:
Mapping and metadata information could not be found for EntityType 'Template001'.
How can I work around this? I definitely need to inherit from the EF classes.
EDIT
Does not seem possible. If that is the case, what would be the best way to implement the following requirement: The template entity stores information about templates that each have their own code to execute. That is why I was trying to derive from the entity in the first place.
It is not supported. You cannot derive a new type from entity and use it instead of the mapped entity type for persistence. If you want to have derived class from entity you must use mapped inheritance where every child is also mapped to the database.
Why do you need to inherit from entity class first of all? If you want to add some simple behavior, use partial class.
Update: Based on comments, it appears that there is possibility that behavior will be extended over the time. In this case, I would recommend using composition/aggregation, not inheritance. Let the classes that need to be extended have an entity as a field. In Raheel's scenario, it would be a class called TemplateLogic with field/property of type Template.
I would like to know if there is a way how to store classes only with behavior to database with nHibernate.
What I mean. I have a solution where I have used decorator pattern, something like on class diagram
Here is the problem what Iam trying to solve. I have a class ClassWithStoredBehaviorInProperty and has a property DesiredBehavior of type IBehavior. Somewhere else I mix up behavior f.e. var beh = new FlyBehavior(new WalkBehavior(new BatmanBehavior)) and store it in DesiredBehavior property. And here is my question. Is there any way how to store this in database with nHibernate and then Load it correctly or I have to do some workaround. If it is possible, how to map it? Thanks
You can have hierarchical data structures handled by NHibernate. From a database perspective, The Decorator Pattern is simply a hierarchical structure where there is only one child node rather than a collection. There is some introductory information here.
So you can quite easily map subclasses of the same hierarchy using the 'table per class hierarchy' approach, where each Decorator becomes a row in the table and points to an Inner Decorator. In your table you use a discriminator column so when retrieving from the database, NHibernate knows what type of class it needs to instantiate. Obviously the 'code' that realises the particular behavior associated with each Decorator would not live in the database.
I have a few classes that read from very delicate tables, which is why I want them to be used by NHibernate as "ReadOnly". Establishing .ReadOnly() on each field map is really sloppy, and I'm not sure I trust it. How do I setup a class to be entirely readonly, as I can easily do with traditional XML mappings?
Edit: The answer does work. I expected it to throw an exception if I tried to save over a ReadOnly() object, but it just silently does so.
Thanks.
With Fluent NHibernate, it's as simple as:
class EntityMap : ClassMap<Entity>
{
public EntityMap()
{
ReadOnly();
// Mappings
}
}
The ReadOnly() property actually does NOT work like you would expect.
Using this property makes sure that the objects that you retrieve are read-only, so you cannot UPDATE them. However, it does NOT prevent the creation of new records or even the deletion of existing records in the database!
I hope the title and following text are clear, I'm not very familiar with the correct terms so please correct me if I get anything wrong. I'm using Linq ORM for the first time and am wondering how to address the following.
Say I have two DB tables:
User
----
Id
Name
Phone
-----
Id
UserId
Model
The Linq code generator produces a bunch of entity classes.
I then write my own classes and interfaces which wrap these Linq classes:
class DatabaseUser : IUser
{
public DatabaseUser(User user)
{
_user = user;
}
public Guid Id
{
get { return _user.Id; }
}
... etc
}
so far so good.
Now it's easy enough to find a users phones from Phones.Where(p => p.User = user) but surely comsumers of the API shouldn't need to be writing their own Linq queries to get at data, so I should wrap this query in a function or property somewhere.
So the question is, in this example, would you add a Phones property to IUser or not?
In other words, should my interface specifically be modelling my database objects (in which case Phones doesn't belong in IUser), or are they actually simply providing a set of functions and properties which are conceptually associated with a User (in which case it does)?
There seems drawbacks to both views, but I'm wondering if there is a standard approach to the problem. Or just any general words of wisdom you could share.
My first thought was to use extension methods but in fact that doesn't work in this case.
I've had some awful experiences trying to abstract LINQtoSQL entities behind interfaces. It was a while ago, but from memory the main problem was that it totally breaks associations. For example, if you have a Customer -> Order relationship, you end up exposing it as an ICustomer, with a collection of IOrders, which means that Customer has to do some awkward mapping to cast it's internal collection of Order objects as IOrders.
Then you have to assume that when an IOrder gets passed back in, that we can cast it to an Order. Otherwise LINQtoSQL can't deal with it, but then that defeats the point of having the interface there in the first place.
I would strongly recommend that you don't try and abstract away the entity classes too much, LINQtoSQL doesn't actually put any real magic in them, the DataContext handles their persistence lifecycle, so they remain testable.
The aspects that I would be looking to hide behind an interface would be the interactions with DataContext, for example using Repository-style classes:
public interface IPhoneRepository
{
IEnumerable<Phone> GetPhonesForUser(User user);
}
public class L2SPhoneRepository : IPhoneRepository
{
private readonly MyDataContext context;
public L2SPhoneRepository(MyDataContext context)
{
this.context = context;
}
public IEnumerable<Phone> GetPhonesForUser(User user)
{
return context.Phones.Where(p => p.User == user);
}
}
Your interface should model how you would like for the objects to be used. Since you are trying to abstract, then the consumer should not have to query the DB. Whether you make it a property, or a separate function call (ie, GetPhones()), is entirely up to you. Since you are completely wrapping things, you'll have to make some choices about how deep/lazily you want to load your objects.
You should add Phones property to IUser and make it nullable, so for a User who don't have Phone, it will be null.
Since you don't want consumers of the API to write queries, than you should implement functions like GetUser().. etc.
Here is a nice list of article abt n-tier application in Asp.net
http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=416
I tend to consider the Linq2Sql related stuff to be an implementation detail of the data access code and, like the real structure of the database, shouldn't necessarily be exposed to other parts of the system.
If your API is going to be consumed by other people it should be cohesive and easy to use and not cluttered by things the consumer doesn't need to know about. If I'm dealing with users and their phones I don't really want to know about DataContexts or (ugh) DataSets.
Also, by keeping the bulk of your code ignorant of the L2S and database you will have an easier time testing, making schema changes (oh, so now the User table needs to keep a history of every change made) or even changing the ORM completely.