Fluent NHibernate mapping class within the entity class - c#

I'm studying Fluent NHibernate now, and have a question about mapping. It's not an issue, but a best practice question.
I know that with Fluent NHibernate there is a new fluent mapping, and it requires a new Class for mapping fields that will be used by the Entity Class. I was wondering, if the Mapping Class is directly linked to the Entity Class (It will map exacly for the entity class), do best practices dictate that they can't be joined within the same .cs file?
Please note that there will be no nesting here.
I.e.: There are Product and a ProductMap classes, both for a Product table on my database, so I'd place both classes within the same Product.cs, like the following:
namespace Business.Entity
{
public class Product
{
...
}
public class ProductMap : ClassMap<Product>
{
...
}
}
If the classes shouldn't be inside the same file, would you care to explain why, and maybe with real examples?
Thanks in advance!

When creating the SessionFactory instance, you will pass a class that tells which assembly has the mapping definitions. Then, using reflection, it'll iterate through all the classes on this assembly that inherit from ClassMap<T>.
That said, for a faster initialisation, it's better to have this assembly as light as possible, and it means that it would be better to have an assembly that would hold only the mappings and not the classes definitions.
AFAIK this is the only difference. Any feedback will be appreciated.

You should design your entities persistant ignorant as much as possible.
That means you shouldn't make Product derive from ClassMap<Product>. But it also means that the ProductMap shouldn't even be in the same project as your entity.
Typically, you would have a DAL project that contains the mapping and a Domain / Business project that contains the entity

You can keep both classes in different files, even in different namespace. but if you are beginner then you can keep entity class in different file and map class in different file within same namespace.
/* Product.cs */
namespace Business.Entity
{
public class Product
{
...
}
}
/* ProductMap.cs */
namespace Business.Entity
{
public class ProductMap : ClassMap<Product>
{
...
}
}

Related

It is possible to use child class to implement Separation of concerns using EF Core?

My goal is async loading of related entities using DBContext.
Let imagine two projects. The first named MyApp.Domain and contains domain entities.
namespace MyApp.Domain
{
public class PlanPage
{
public Guid Id { get; set; }
}
}
namespace MyApp.Domain
{
public class PlanPageDay
{
public Guid Id { get; set; }
public Guid PlanPageId { get; set; }
}
}
The second project named MyApp.Infrastructure.EntityFramework and contains configuration of projection entities to database. It also contains class which extends domain entity and implements Entity framework specific logic.
namespace MyApp.Infrastructure.EntityFramework.Models
{
public class PlanPageEntity : PlanPage
{
private readonly ApplicationDbContext _applicationDbContext;
protected PlanPageEntity(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public ICollection<PlanPageDay>? Days { get; set; }
public async Task<ICollection<PlanPageDay>> GetDays()
{
return Days ??= await _applicationDbContext.PlanPageDays
.Where(pd => pd.PlanPageId == Id)
.ToListAsync();
}
}
}
The purpose of this example is simple. We separate infrastructure code from domain code. Look how do we plan to use this concept:
// Entity initializing code. Placing somewhere in domain logic.
var plan = new PlanPage(/*some constructor arguments*/);
// Entity loading code. Placing somewhere in infrastructure implementation.
public async Task<PlanPage> GetPlanPage(Guid id)
{
return await _applicationDbContext.Set<PlanPageEntity>().FindAsync(id);
}
Note that we tell to Entity framework to use child class (PlanPageEntity) so it can handle all specific things that it can.
The question is: Is it possible to configure the EF so that it allows us to use this concept?
As requested here's a little more details for my opinion stated in the comments.
The main reason why I think your current approach is a bad idea is that it violates the separation of concerns design principle: when you are mixing domain models with data access models, you make your domain logic completely dependent on how you model the data in your database. This quickly limits your options because the database may have some restrictions on how you can model your data that doesn't fit well with the domain logic you want to implement as well as making maintenance difficult. E.g. if you decide to split up one DB table into two then you might have a big task ahead of you in order to make your domain logic work with those two new models/tables. Additionally, making performance optimizations in your database easily becomes a nightmare if not thought through ahead of time - and you shouldn't spend time thinking of optimizing your system before it's necessary.
I know this is a little abstract since I don't know much about your domain but I'm sure I could find more arguments against it.
Instead, separating data access models (and in general all external data models) from your domain models makes it much easier to maintain: if you need to make some changes to your database, you simply need to update the logic that maps the data from your data access models to your domain model - nothing in your domain logic needs to change.
In the examples you have given, you have already logically separated your domain models and data access models into two separate projects. So why not follow through with that thought and separate the two with a binding/mapping layer in-between?
Is it possible to configure the EF so that it allows us to use this concept?
Yes. Essentially you have DTO's, and your Entities derive from your DTOs. So when you fetch an Entity you can return it directly. But if you wouldn't be able to attach a non-Entity, so you'd have to map it. It's going to be inconvenient, and like 99.999% of bespoke entity and repository designs, will be ultimately a waste of time.
This is somewhat similar to the what EF already does for you. Start with persistence-ignorant Entity classes, and introduce persistence-aware runtime subtypes for scenarios that require them, which is basically just Lazy Loading.

Entity mapping library case for two differently structured entities

I've been looking for an entity mapping library to save me from writing tons of property mapping code. So I found AutoMapper, AgileMapper and Mapster. As I see it, all help with similarly structured entities. But in my case, my two entities are not even remotely alike.
One property for example:
public class EntityA
{
public int PropertyA;
}
public class EntityB
{
public Inner1 inner1;
}
public class Inner1
{
public Inner2 inner2;
}
public class Inner2
{
public double nothingLikeTheOtherPropName
}
And EntityA.PropertyA maps to Inner2.nothingLikeTheOtherPropName.
So, the question is: Will any entity mapping library help if the two entities are structurally different?
AutoMapper can be configured to map the different properties, but there’s no way to automate completely different names.
The good thing is that you’d only do it once and everywhere else it’s used will be correct.
Here’s a previous answer
How to specify mapping rule when names of properties differ

Map Multiple Tables to One Table Produces Foreign Key Column for each in Fluent NHibernate

I want to Point 3 tables Property, Business, Automobile to single Table named Utility.
Using Fluent NHibernate, I followed
public UtilityMap()
{
// some Mappings
References<Automobile>(x => x.Automobile, "LeaseRefId").Cascade.None();
References<Business>(x => x.Business, "LeaseRefId").Cascade.None();
References<Property>(x => x.Property, "LeaseRefId").Cascade.None();
}
and in Each table that maps to the Utility, I followed
public AutomobileMap()
{
//Some Mappings
HasOne<Utility>(x => x.CommonDatas)
.Cascade.All();
}
"I want to have a single column in Utility Table that can store the
references of all the three (Automobile, Business, Property) tables.
But fluent Nhibernate is creating foreing key columns for each of the
table referenced. I want to avoid this."
Is there any way to achieve this??
Please suggest
Thanks in Advance.
For this to work as you expect, you'll need to have a base class for Automobile, Business and Property classes. Let's call it LeaseSubject. Presumably, you already have something like that in your domain model.
Your Utility class should have only one property, instead of three you have now:
public virtual LeaseSubject LeaseSubject { get; set; }
This way you not only have easier mapping, but also promote the maintainability of your code. What if at some later time you decide to have one more lease subject, i.e. Yacht? Instead of adding another Yacht property to your Utility class, you just need to inherit from LeaseSubject, and it could be contained within the LeaseSubject property on Utility class.
Now you could map your Utility simply as:
public UtilityMap()
{
// Other mappings...
References(x => x.LeaseSubject, "LeaseRefId");
}
For mapping Automobile, Business and Property classes, you would use one of three available NHibernate inheritance strategies:
table per class hierarchy
table per subclass
table per concrete class
For FluentNHibernate inheritance mapping, take a look here.
Since you already have separate tables, I believe the correct strategy for your case would be Table per concrete class. You can find some more info in this article.

Extending Entity Framework Model to include new property

I'm new to EF so please excuse me if this is a noob question.
Basically, we have a EF model set up using Model First for our 'platform' project and is shared across many applications which we build on top of this platform. In some of these applications we want to extend the classes to include additional properties without changing the model in the platform. Is this possible with EF 4 and how would I be able to do it without modifying the .edmx file?
I notice that the generated classes are all partial so potentially I could create a new partial class with the same name to include the new properties but is there any mappings that need to be taken care of?
p.s. under normal circumstances I'd have preferred to use inheritance and create a new class to hold the new properties instead but again, I don't know how to do that with EF.. any enlightenment here will be much appreciated!
Many thanks,
You cannot use inheritance because once entity is loaded from the data source EF will not know about inheritance and because of that it will instantiate base type without your properties instead of derived type with your properties. Any inheritance must be mapped in EDMX if EF have to work with it.
Using partial class will solve your problem but:
All parts of partial class must be defined in the same assembly
Properties from your partial part are not persisted to the database
Properties from your partial part cannot be used in linq-to-entities queries
EF generates partial classes. So to extend MyEntity, create a MyEntity.cs file with
partial class MyEntity
{
public string MyExtraProperty {get;set;}
}
edit: in the same namespace as your generated entities
I agree with adding additional properties to partial class of your entities (as you and Kaido said).
This way you can freely add the properties you want, without modifying generated classes and if you generate your model again (or update it from DB), your partial class is not modified.
In my opinion, adding properties to partial classes of generated entities is the way to go.

Corrupting POCO Domain Model when creating LINQ Entity Classes?

Say I've got a domain model created from C# classes like this:
public class MyClass
{
public string MyProperty { get; set; }
}
Along with the model, I have defined repository interfaces classes for IoC.
Now, I'm trying to turn this POCO domain model into a set of Entity classes using LINQ mapping. (This approch was recommended in a book I'm reading on MVC.) In the example above this was easy enough to do with a few attributes without impacting the 'plain oldness' of the classes:
[Table]
public class MyClass
{
[Column]
public string MyProperty { get; set; }
}
The problem comes when I start to map associations, change modifications and such. It seems that I'm quickly destroying the original concept of the domain model, and instead simply creating a set of LINQ-to-SQL classes. Am I missing something? Are these classes still the correct place for business logic? Will I still be able to and should I continue to load data into these classes from non-LINQ, non-DB sources?
Thanks
This post, also on SO, answers my question: (Thanks Google)
Entity classes decoupled from LINQ to SQL provider for implementing the Repository pattern. How?
EDIT:
Well maybe not, is this a common complaint about entity classes?
ANOTHER EDIT:
Ok, so basically this cannot be done at the moment, but with .NET 4.0 it is supposed to be possible.
There have been several other question like this.
I played with EF4 this week end, you can follow Julie Lerman blog post serie to implement a Repository pattern with EF4. It works well, although it's no yet completely straight forward...
As far as I know there is no way to do this with EF3.5. Good luck.

Categories

Resources