NHibernate foreign key set - nhibernate

I have a:
class Garage {
int garageID;
ISet<Car> cars
}
should the cars class have garageID as one of its properties, as in:
class Car {
int carID;
int garageID;
String name;
}
That is how it appears in the database, but wondering if the classes on the many side are supposed to have the foreign key as a property or if the ORM just adds that in when performing the SQL (assuming you can specify it in the mappings file).

In short: No. (and yes the ORM will take care of FK based on your mapping files)
The "Car" table will have the GarageId in it but you should not add it to the Car class.
You can have a bi-directional relationship (although opinions vary on whether these are a good idea).
A bi-directional relationship would make the Car class look like this:
public class Car {
public virtual int Id {get; set;}
public virtual Garage Garage {get; set;} //You can traverse back up to Garage
public virtual string Name {get; set;}
}
If you would like me to post the Fluent/XML maps let me know.

Related

Should entities in a AggregateRoot also become an AggregateRoot

I'm trying to setup my domain models around the DDD principles. Right now I have the following class:
class Customer : AggregateRoot
{
public string CustomerReference {get;set;}
public string CustomerName {get;set;}
public string List<Adult> Adults {get;set;}
public string List<Child> Children {get;set;}
}
Creating a Customer is the essence of the application, so I made that class an AggregateRoot. Because a lot of
times the end user will want to find a customer by its CustomerReference key.
But then again, sometimes the end user wants to search by the name of a Child, to find out the Customer info. Or even sometimes
by the name of an Adult.
I'm not sure if that means that I should make the Child and Adult classes also an AggregateRoot? Or should I always
start searching from the Customer AggregateRoot if I want to search by a Child or Adult name?
No - aggregate root members are only accessible via the aggregate root.
however, If you are wanting to manipulate Adult/Child entities on their own, it is likely you don't need the full Adult and Child entities as part of the customer root. If this is the case replace those collections of entities with collections of Id's and rely on the fully entities to be provided to any functions that require their attributes.
class Customer : AggregateRoot
{
public string CustomerReference {get; private set;}
public string CustomerName {get; private set;}
public string IEnrumerable<AdultId> Adults {get; private set;}
public string IEnrumerable<ChildId> Children {get; private set;}
public void RegisterAnAdult(Adult adult) {...}
public void RegisterAChild(Child child) {...}
}
I emphasised If because this looks a little bit off unless your system is huge and Adult and Child can belong to multiple customers. (How do you handle when an child grows up to transition to an adult?)
As #mgonzalezbaile said, don't model your domain based on queries - searching is a whole different thing - model it on business behavior. (For more info start with [http://www.zankavtaskin.com/2016/06/applied-domain-driven-design-ddd-part-7.html])
Finally, in your example the properties are publicly set-able, if this is on purpose then it might be worth stepping back and re-reading the literature on DDD a few more times, public settable properties potentially allow your entity to move to an invalid state, something that DDD tries to avoid.

Is this a legitimate use of TPC inheritance in EF Code First?

I'm designing a fairly complex hosted web app that needs to support multiple "Teams" that are effectively isolated from each other. For example, the tables People, Areas, Reports, etc. will have intermingled data populated by the teams at Corporation A, B, C, and on down the line, and the user from Corporation A has logged in, he should only ever see data relevant to corporation A. My plan is to create a relationship between Team and (nearly) every other type and to use a repository to access all those other types, and always query where TeamId matches the TeamId of the person logged in.
So since I want to have
[ForeignKey("Team")]
public int TeamId { get; set; }
public virtual Team Team { get; set; }
on almost every class, I was thinking it might be nice to put those in an abstract class and inherit those properties:
public abstract class OfTeam {
[ForeignKey("Team")]
public int TeamId { get; set; }
public virtual Team Team { get; set; }
}
public class Person : OfTeam {
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
But, I realize this isn't truly what inheritance is about. So I'd like to know
Will this even work?
Is it a terrible idea?
I misunderstood at first and though you were inheriting team, which would have been a bad idea.
If you ever query db.OfTeam then it will union together every single table that inherits from it, which will perform terribly. Scroll down to see the SQL produced here:
http://weblogs.asp.net/manavi/archive/2011/01/03/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-choosing-strategy-guidelines.aspx
Otherwise the actual DB structure should be identical to if you simply put TeamId/Team on all of those classes directly.
I personally wouldn't do this because it adds little value and could potentially cause headaches down the road.
Instead you could just have an IOfTeam interface on all those classes if there is a need to interact with them in a generic manner for some reason.
As a side note I've done something similar and usually cache TeamId somewhere easily accessible, such that I can anywhere do CurrentIdentity.TeamId and pass it to a query. This allows methods on repository pattern like GetPeople to apply a where criteria with that filter before returning the IQueryable.

Fluent NHibernate automapping: One-to-many entities, many-to-many backend?

My goal is to use NHibernate schema generation along with Fluent NHibernate's automapper to generate my database. I'm having trouble with what I'll call "unidirectional many-to-many relationships."
Many of my entities have localized resources. A single class might look like this:
public class Something {
public virtual int Id {get; private set;}
public virtual Resource Title {get;set;}
public virtual Resource Description {get;set;}
public virtual IList<Resource> Bullets {get;set;}
}
The Resource class doesn't have any references back; these are entirely unidirectional.
public class Resource {
public virtual int Id {get; private set;}
public virtual IList<LocalizedResource> LocalizedResources {get;set;}
// etc.
}
public class LocalizedResource { //
public virtual int Id {get; private set; }
public virtual string CultureCode {get;set;}
public virtual string Value {get;set;}
public virtual Resource Resource {get;set;}
}
Without the IList<Resource>, everything is generated as I'd want -- Resource ID's are in the Title and Description fields. When I add in the IList though, NHibernate adds the field something_id to the Resource table. I understand why it does this, but in this situation it's not a sustainable approach.
What I want is to create a junction table for the bullets. Something like:
CREATE TABLE SomethingBullet (
Id int NOT NULL PRIMARY KEY IDENTITY(1,1),
Something_Id int NOT NULL,
Resource_Id int NOT NULL
)
This way when I add the other twenty-odd entities into the database I won't end up with a ridiculously wide and sparse Resource table.
How do I instruct the Automapper to treat all IList<Resource> properties this way?
Every many-to-many is in fact composed with one-to-many's in object model. If your relationship doesn't need to be bidirectional, just don't map the second side. The mapping on your mapped side is not affected at all:
HasManyToMany(x => x.Bullets).AsSet();
In this case, NHibernate already knows that it needs to generate the intermediate table.
See also this article for many-to-many tips.
:)
The only way I found to make this work with automapping is by constructing your own custom automapping step and replacing the "native" HasManyToManyStep. It's either that or an override, I'm afraid.
I lifted mine off of Samer Abu Rabie, posted here.
The good news is that Samer's code, so far, seems to work flawlessly with my conventions and whatnots, so, once it was in place, it was completely transparent to everything else in my code.
The bad news is that it costs you the ability to have unidirectional one-to-many relationships, as Samer's code assumes that all x-to-many unidirectional relationships are many-to-many. Depending on your model, this may or may not be a good thing.
Presumably, you could code up a different implementation of ShouldMap that would distinguish between what you want to be many-to-many and what you want to be one-to-many, and everything would then work again. Do note that that would require having two custom steps to replace the native HasManyToManyStep, although, again, Samer's code is a good starting point.
Let us know how it goes. :)
Cheers,
J.

Reference an object from a column in another table

I have the following object model:
class ObjectA{
public string Description {get;set;}
}
class ObjectB{
public string Description {get;set;}
public ObjectA A {get;set;}
}
class ObjectC{
public string Description {get;set;}
public ObjectB B {get;set;}
}
class ObjectD{
public string Description {get;set;}
public ObjectC C {get;set;}
public ObjectA A {get;set;}
}
My tables are as follows:
A: ID(int), DESCRIPTION(string)
B: ID(int), DESCRIPTION(string), A_ID(int)
C: ID(int), DESCRIPTION(string), B_ID(int)
D: ID(int), DESCRIPTION(string), C_ID(int), A_ID(int)
In table D A_ID is a foreign key to the primary key of table A. This was originally done so that you could easily access ObjectA from ObjectD: ObjectD.A. This is causing the ID from table A to have to be added to every table that wants to access ObjectA in this manner de-normalizing the database (imagine having ObjectE, and ObjectF that all want to easily access ObjectA). In this case ObjectB will always have a reference to ObjectA.
I'd like to get rid of the reference to A_ID in all of my tables but I want to be able to easily access ObjectA from my classes. I know I could do ObjectD.ObjectC.ObjectB.ObjectA to get ObjectA when needed but that seems to defeat the purpose of lazy loading my objects.
How can I map my ObjectD so that I can have direct access to ObjectA without having ObjectA's ID in ObjectD's table?
Note: I'm using hbm/xml files to map my classes.
It seems to me you either live with the redundant data for performance reasons or you don't. I can't conceive of a third option. (But there are better NHibernate minds out there that may correct this view).
If the reads of these objects are much higher than the writes and the use cases require access to ObjectA most of the time you're working with an ObjectD then the redundancy is fine. Otherwise the ObjectD.C.B.A approach you refer starts to become more attractive.

Fluent NHibernate / NHibernate Inheritance Question

Possibly a dumb question but I have a number of entities all inheriting from a base entity. The base entity does not have a table in the database. Each entity has its own table and the table definition is exactly the same. Extremely simplified example of the code is below.
public abstract class BaseEntity
{
public virtual string someProperty {get; set;}
}
public class Entity1 : BaseEntity{}
public class Entity2 : BaseEntity{}
public class CompletelyDifferentEntity
{
public virtual IList<BaseEntity> {get; set;}
}
I created the mappings for the entities. In my other domain classes if I reference the concrete classes everything works fine but if I change my other classes to reference BaseEntity instead I get a mapping Exception because the BaseEntity is not mapped. Is this something where I should use a subclass discriminator? I guess I'm not seeing the correct way to do this if the base doesn't have an associated table and the subclasses don't have a specific column that is different between the table definitions.
You have to use one of three available inheritance mappings strategies. From your description, you should consider using table-per-concrete-class mapping, or change your db scheme.
You can find more information about pros and cons of strategies here: https://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html.