Corrupting POCO Domain Model when creating LINQ Entity Classes? - c#

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.

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 Framework method to return entities as a property

Hi my first question here so forgive me if its not asked in the correct manner.
I'm new to the entity framework and have a database first model.edmx file setup.
What I would like to know is if there is a way to setup a property on an entity that returns a method:
eg.I have a Customer entity with various properties.
Using Linq I could do something like context.Customers.ToList(); to return all the customers.
How could I create a property/method that would look like this context.Customers.getAll();
I could then create others like context.Customers.getVIP(); with cetain conditions.
You need a class that having all logics of an entity...
This link will help you - Implementing Repository Pattern With Entity Framework
The answer provided above is the proper and the right way to do it. But, if for any reason you want to do it the other way, you can have a partial class for your data context
public partial class EntityContext
{
public List<Plant> GetAllCusomters()
{
return Customers.ToList();
}
}
A word of warning though, this is by no means a proper way to do it and certainly not the recommended approach.

DDD with EF Code First - how to put them together?

I am learning DDD development for few days, and i start to like it.
I (think i) understand the principle of DDD, where your main focus is on business objects, where you have aggregates, aggregates roots, repositories just for aggregates roots and so on.
I am trying to create a simple project where i combine DDD development with Code First approach.
My questions are: (I am using asp.net MVC)
DDD Business Objects will be different than Code First objects?
Even if they will probably be the same, for example i can have a Product business object which has all the rules and methods, and i can have a Product code first (POCO) object which will just contain the properties i need to save in database.
If answer to question 1 is "true", then how do i notify the Product POCO object that a property from business object Product has been changed and i have to update it? I am using an "AutoMapper" or something like this?
If the answer is "no", i am completely lost.
Can you show me the most simple (CRUD) example of how can i put those two together?
Thank you
Update I no longer advocate for the use of "domain objects" and instead advocate a use of a messaging-based domain model. See here for an example.
The answer to #1 is it depends. In any enterprise application, you're going to find 2 major categories of stuff in the domain:
Straight CRUD
There's no need for a domain object here because the next state of the object doesn't depend on the previous state of the object. It's all data and no behavior. In this case, it's ok to use the same class (i.e. an EF POCO) everywhere: editing, persisting, displaying.
An example of this is saving a billing address on an order:
public class BillingAddress {
public Guid OrderId;
public string StreetLine1;
// etc.
}
On the other hand, we have...
State Machines
You need to have separate objects for domain behavior and state persistence (and a repository to do the work). The public interface on the domain object should almost always be all void methods and no public getters. An example of this would be order status:
public class Order { // this is the domain object
private Guid _id;
private Status _status;
// note the behavior here - we throw an exception if it's not a valid state transition
public void Cancel() {
if (_status == Status.Shipped)
throw new InvalidOperationException("Can't cancel order after shipping.")
_status = Status.Cancelled;
}
// etc...
}
public class Data.Order { // this is the persistence (EF) class
public Guid Id;
public Status Status;
}
public interface IOrderRepository {
// The implementation of this will:
// 1. Load the EF class if it exists or new it up with the ID if it doesn't
// 2. Map the domain class to the EF class
// 3. Save the EF class to the DbContext.
void Save(Order order);
}
The answer to #2 is that the DbContext will automatically track changes to EF classes.
The answer is No. One of the best things about EF code-first is that it fits nicely with DDD since you have to create your business objects by hand so do use your EF models to be equivalent to DDD entities and value objects. No need to add an extra layer of complexity, I don't think DDD recommends that anywhere.
You could even have your entities to implement an IEntity and you value objects to implement IValue, additionally follow the rest of DDD patterns namely Repositories to do the actual communication to the database. More of these ideas you can find this very good sample application in .NET, even though it doesn't use EF code first, it's still very valuable: http://code.google.com/p/ndddsample/
Recently I've done similar project. I was following this tutorial: link
And I've done it this way: I've created Blank solution, added projects: Domain, Service and WebUI.
Simply said in domain I've put model (for example classes for EF code first, methods etc.)
Service was used for domain to communicate with world (WebUI, MobileUI, other sites etc.) using asp.net webapi
WebUi was actually MVC application (but model was in domain so it was mostly VC)
Hope I've helped
The Pluralsight course: Entity Framework in the Enterprise goes into this exact scenario of Domain Driven Design incorporated with EF Code First.
For number 1, I believe you can do it either way. It's just a matter of style.
For number 2, the instructor in the video goes through a couple ways to account for this. One way is to have a "State" property on every class that is set on the client-side when modifying a value. The DbContext then knows what changes to persist.
Late question on this topic.
Reading Josh Kodroff's answer confirms my thoughts about the implementation of a Repository to, for instance, Entity Framework DAL.
You map the domain object to an EF persistance object and let EF handle it when saving.
When retrieving, you let EF fetch from database and map it to your domain object(aggregate root) and adds it to your collection.
Is this the correct strategy for repository implementation?

Interface (interface in interface) in the Entity Framework

I've got two entities in the entity framework. Now I want to seperate them by putting an Interface of the DAL entity into the Domain.
So the end result would be:
DAL
Person : IPerson (EF Entity)
Book : IBook (EF Entity)
Domain
Interfaces (Folder)
IPerson
IBook
Person (Domain entity)
Book (Domain entity)
Now the problem is, should my Dal.Person have a virtual Book or IBook?
How should both the DAL.Person, IPerson and Domain.Person look like (give me just really small example for the interfacing)
EF doesn't support working with interfaces so you cannot have public virtual IBook ... in your Person entity if you want to use it as navigation property handled by EF.
The answer to your question entirely depends on your objective here.
If you are creating domain level Interfaces with the rationale that you might (at some stage later) swap over the DAL from Entity Framework to something entirely different (such as a 3rd party web-service, or perhaps xml serialisation) - then you will be aiming to completely seperate any concrete logic between the Domain and the DAL.
Where possible, you want your Domain to operate on the Domain entites/interfaces and your DAL to operate on DAL entities/interfaces, whilst implementing the interfaces specified in your Data Access
Therefore, your DAL object DAL.Person should contain a Book object, and implement from the IPerson interface at a domain level.
I'll give some examples as requested:
#region Domain Objects
public interface IPerson
{
List<IBook> Books { get; private set; }
}
public interface IBook
{
string Name { get; private set; }
}
#endregion
#region DAL/Entity Framework Auto Generated classes
public class Person : IPerson
{
public List<Book> Books {get; private set;}
}
public class Book : IBook
{
public string Name { get; private set; }
}
#endregion
Contrary to Jodrells comment, I think that if there was a requirement to 'Hot-Swap' the Data Access Layer there could be a case for the DataAccess layer implementing the interface contracts described in the Domain layer.
To be honest though, it is rare that I have seen this requirement - and usually you are best off extending the auto-generated Entity Framework classes (through partial) and passing around the application, removing the duplication that would be required by specifying the domain objects and contracts themselves.
So in essence, your Entity-Framework classes becomes your Domain layer.
And I should mention that you should use POCO classes as per comments above
I've not seen Interfaces used to decouple EF. I know they are used for decoupling with dependency injection, but perhaps there is too much going on with EF behind the scenes for this to work (dynamic proxies, change detection).
I'd suggest implementing a Repository layer.
Step 1
Start with the simplest pattern - model (Person and Book) in a domain and EF in a DAL layer, using the standard EF procedure for code first. EF implements repository features in the DbSet<Person> and DbSet<Book> (but of course this type of repository is locked into EF).
Make a deliverable app work with this pattern, you can demo functionality quite quickly. This allows you to focus on app logic and not worry too much about persistence.
Step 2
Put a repository class or classes between domain and DAL. Replace the domain calls to DbSet<Person> and DbSet<Book> with calls to IQueryable<Person> and IQueryable<Book> in the repository. The repository collections initially just point at the EF DbSet<> collections.
Implement Save() in the repository as well. Initially, it just calls DbContext.SaveChanges().
Check the functionality stays the same.
Step 3
Replace the source of the repository IQueryable<>'s with whatever is equivalent in your new DAL. This may or may not be tricky, depending on the shape of the new DAL.
I followed this kind of process - started with an XML serialized DAL, moved it to EF, refactored one table back to a local XML file, and next step will be to refactor another table to a web service on an ESB.
BTW, you mention replacing EF with SQL for performance. We found EF slow for bulk inserts, because of the row-by-row style it uses.
To get around this, I implemented SqlBulkCopy within the EF based repository (instead of wholesale replacement of EF which has other features we really liked). It's quick, but takes a while to piece together.
I've been having this problem for AGES.
In the past I have used DTOs with AutoMapper, but this never seemed very elegant, but I think I've found a slightly neater way - have a look and see if it suites your design.
Basically you expose TWO links in your - in your concrete class - one implemetents the Ibook Book and one that implements Book BookNavigation
the first one implements the interface requirements (Ibook) and the second implements a concrete class to make EF Happy. You then bind the two to the SAME underlying private Book book.
I explain it in more detail here:
http://bretthargreaves.wordpress.com/2014/11/11/entity-framework-and-interface-issues/

How to use Entity Framework in Enterprise application

i have some questions of how to use the Entity Framework in an enterprise application.
First of all, i work with ADO.NET for many years now and i use objects to reflect the data that i get from the database provider.
Every time i want to change something or insert something into the database.
I just call a Save() method and get the job done.
Every object has a DatabaseManager that manage the queries to the DataAccess layer.
For example
public class Article{
public int ID{get;set;}
public string Title{get;set;}
.....
public bool Save(){
if(this.ID == -1){
return new ArticleDatabaseManager().InsertArticle(this);
}else{
return new ArticleDatabaseManager().UpdateArticle(this);
}
}
}
public ArticleDatabaseManager : DatabaseManager
{
...ADO.NET code
}
I don't know if i have to use the same architectur or change all the way i use this objects in my application.
I thought if i create something like the above i can do something like this :
public class Article{
public int ID{get;set;}
public string Title{get;set;}
.....
public bool Save(){
if(this.ID == -1){
return new ArticleDatabaseManager().InsertArticle(this);
}else{
return new ArticleDatabaseManager().UpdateArticle(this);
}
}
}
In the Each DatabaseManager implements some Link To Entities or even EntitySQL to do the same job like the old DatabaseManager does.
Fill the Business models with the values that i from the Entity Objects.
Then i could work with the Business as before and just any time i want to do some changes i communicate via EntityFramework to the Database.
Sould i implement something like the above?
Sould i just inherit the previous business objects to the entity objects?
EX :
public class Article : ArticleEntity
{
//some properties for validation etc
}
Sould i use something completely different?
I Just Don't knwo:/
I have no experience with other ORM. Just mine hand written "ORM" System.
Thank you very much.
I'm sorry for my lack of English and i know that i ask too much in a single question...
But moving from one technology to an other for a dinosaur like me is like i change Country:/
Did you at least try to use some EF tutorial? If not it is time to do that because we cannot explain you everything about EF in single answer (even in multiple - that is not purpose of SO to replace tutorials and learning materials). That should give you pretty clear answer about all your stuff related to your database managers.
In general what you did till know is very close to Active record pattern. If your objects also has static methods used to retrieve object from database it is Active record pattern. When using EF you usually don't use this pattern and you don't need any database manager. EF is build around class which is called context and this context works as your database manager for all entities you are using. It is possible to add saving and retrieval methods to entities but because it breaks separation of concerns and it makes your entities heavily dependent on EF and persistence (trend is to make them completely independent = POCO) it is usually not used.
Don't derive any custom class from entity. EF will not be able to use your derived type. Use entity mapped in EF as your class and add all custom properties and methods directly to this class (you can even create that class from scratch if you don't want to use code generators). In case of generated entities you can add custom code in partial classes. If you don't use EF entity as your object you will have to manually handle conversion from one to other (or use some tool like AutoMapper).
EF is not able to work with XML column - it will handle it as string. Especially if you plan to use these data for some ordering or filtering and if they have fixed structure you should model them as separate tables / entities. If it is really just structured content (with dynamic structure) you can use it as XML string.

Categories

Resources