Do I need to use POCO Classes with Entity Framework 6 - c#

The following class was Auto generated from a template using the Entity Framework Model.
namespace Entities
{
using System;
using System.Collections.Generic;
public partial class Country
{
public Country()
{
this.Regions = new HashSet<Region>();
}
public long CountryId { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public bool Preferred { get; set; }
public System.DateTime LastChanged { get; set; }
public virtual ICollection<Region> Regions { get; set; }
}
}
I have a Wcf web service that returns POX (Xml) and Json only. I am wanting to return my own serialised object like;
public class MyResponseObject
{
public int RequestId {get;set;}
public List<Country> CountryList {get;set;}
//other properties
}
But I don't want to return the Regions ICollection.
The object can then be returned using something like
Newtonsoft.Json.JsonConvert.SerializeObject()
Am I best returning my own serialised POCO object in this manner ?

In projects like these, your classes can be split into two types:
Database entity objects (what Entity Framework works with)
Data contract objects (what WCF or your web-service works with)
While it is possible to use the same objects for both, it is not recommended because the database entity objects are an internal implementation concern that is separate from the external interface (your webservice). You might add or remove columns to your database table and not want your API contracts to change. But usually you'll want to hide information from service-consumers, like a database table Users ( UserId, Password ), you definitely don't want the Password property going out!
Another reason not to is that you later might want to add attributes to your webservice contract classes (e.g. to control output formatting or input validation), adding these to entity objects is painful, if not impossible in some cases.
I know it sounds like a needless duplication of work as the majority of classes will have identical members, but it makes sense from a long-term perspective.
Fortunately tools like AutoMapper can speed-up the process of copying data from your database entity objects to your data contract objects.

Related

Where do derived or inferred properties belong in an application?

I'm building an app using code first and generating the DB.
I can no longer modify the DB so, I can't add/change columns and tables. But the Domain Model (not sure if I'm using the term correctly) requires new properties (that are part of the domain) that can be inferred from the database data, but do not exist explicitly.
My database stores sales info for houses. So I have two tables, Houses and Sales. The tables are related by houseID. Now I want houses to have a property called LastSaleDate, but I can't change the underlying database.
So, How would I properly construct this new property and add it into the appropriate layer? Here is what my poco/entities look like. Just pseudo coded...
[I am trying to learn all I can about the tools and methods I use. I may be completely wrong on all my assumptions and maybe I am to add it to my pocos. If that is the case please explain how that would work]
[Table("HOUSE_TABLE")]
public class house {
//some properties
public int HouseID {get;set;}
}
[Table("SALE_TABLE")
public class sale {
//some properties
public int HouseID {get;set;
public int SaleID {get;set;}
public datetime SaleDate {get;set;}
public virtual House House {get;set;}
}
I almost feel like this would create 2 levels of mapping. Though, I don't believe I've ever seen this done in any code I've seen online.
poco -> AutoMapper?? -> entities -> Automapper -> viewModels
This logic most likely belongs on the Entity. Entities should have both data and behaviour. What you seem to be describing is some behaviour that is exposed as a property. So, you should add a property for the derived value to your entity. By default, if the property only has a getter, then EF will not try to map the value to the database.
For example:
[Table("HOUSE_TABLE")]
public class house
{
//some properties
public int HouseID {get;set;}
public virtual ICollection<Sale> Sales { get; set; }
public DateTime LastSaleDate
{
get
{
return this.Sales.OrderByDescending(s => s.SaleDate).First();
}
}
}

POCO's, behavior and Peristance Igorance

From what I have read POCO classes should be persistence ignorant and should not contain references to repositories.
Q1. Given the above, how would I populate the QuestionBlocks collection? I have read that POCO's should contain behavior so you don't end of with an anemic model, so I'm kind of confused as how one is supposed to do that without persistence. If that's the case then what kind of behavior would you put in a POCO?
Ex:
public class Survey
{
public int SurveyId { get; set; }
public string Title { get; set; }
public int BrandId { get; set; }
public DateTime Created { get; set; }
public List<SurveyQuestionBlock> QuestionBlocks { get; set; }
[ResultColumn]
public string Name { get; set; }
/// <summary>
/// Constructor
/// </summary>
public Survey()
{
Created = DateTime.Now;
QuestionBlocks = new List<SurveyQuestionBlock>();
}
}
I would append another view: POCO states for objects which are not dependent on any framework. The wiki definition of a POJO is much more meaningful to me then the one for POCO:
http://en.wikipedia.org/wiki/Plain_Old_Java_Object
To paraphrase the wiki definition of the POJO, we can say that POCO object might not be forced to:
I. Extend prespecified class:
public class MyClass : AnyFramework.ObjectBase {...
II. Implement prespecified interfaces
public class MyClass : AnyFramework.IHaveDependency {...
III. Contain prespecified attribute
[AnyFramework.KeyAttribute]
public class MyClass {...
Given this (almost anything else is allowed) in the meaning of taking care about the object state. Other words, if object will check Business logic, it is correct.
But any POCO object can be used in a framework. Today it is mostly for ORM which is responsible for persistence. All application tiers are working with POCO objects, while data layer is responsible for loading and persisting (CRUD). This is mostly done via Proxies of these POCO objects.
So, POCO could be used as full business object, which can take care about itself (check correctness of collection items, properties...). This makes it different from DTO
Given the above, how would I populate the QuestionBlocks collection?
When reading from a database, the persistence infrastructure should populate the QuestionBlocks collection - reconstitution. Reconstruction should not invoke behavior, it should only set appropriate fields on the POCO. This is the responsibility of the repository. A repository is typically referenced from an application service, which sets up the stage for invoking entity behavior.
If that's the case then what kind of behavior would you put in a POCO?
The behavior in the POCO entity should be concerned with making changes to the entity itself as well as maintaining invariants - ie ensuring the integrity of the entity. In your example, the simplest kind of behavior on the POCO should be method for adding a new question block to the collection on the survey. Ideally, you would make many of the properties on the survey entity read-only:
public class Survey
{
public int SurveyId { get; private set; }
public string Title { get; private set; }
public int BrandId { get; private set; }
public DateTime Created { get; private set; }
public IList<SurveyQuestionBlock> QuestionBlocks { get; private set; }
public string Name { get; private set; }
public void AddQuestionBlock(string questionBlockInfo)
{
this.QuestionBlocks.Add(new SurveyQuestionBlock(...));
}
public Survey()
{
Created = DateTime.Now;
QuestionBlocks = new List<SurveyQuestionBlock>();
}
}
The persistence layer should be able to set the values of the read-only properties via reflection. You can go a step further and only expose the question blocks collection as a read-only collection to ensure that it can only be modified from within the entity itself.

Altering Domain Entities When Changing Persistence Layer

In my app, I've been using a DB that stored its IDs as strings. The DB also stored another property (Etag) for each document/row. Because of that, I've had my domain entities derive from this base class:
public class EntityBase : NotifyPropertyChangedBase
{
public string Id { get; set; }
public Guid ETag { get; set; }
}
Now I'm adding another data layer to my application, and I don't want to remove the old one. It would be nice to be able to switch and use a particular data layer based on a run-time decision. The issue is that I want to store Id as an int in the new DB. And ETag is an unnecessary concept in that new DB.
I'm struggling with how to manage this change. If I change EntityBase.Id to an int, then the old data layer won't compile. I'd like to use a certain EntityBase if using the old data layer, and a different EntityBase if I'm using the new data layer. That's just one thought. Maybe there's a better approach? Any suggestions on how I can make this work?
By the way, I believe that persistence layer issues shouldn't work there way up into domain layer objects (like Id being a string or int). However, it's too late, and this is the situation in which I find myself. I'm hoping someone has some good advice on how to proceed.
I was thinking about adding an Id2 to EntityBase:
public class EntityBase : NotifyPropertyChangedBase
{
public string Id { get; set; }
public int Id2 { get; set; } // New property for new DB only
public Guid ETag { get; set; }
}
Then, in my new DAL mapping, I would map the Id column in the table to Id2 instead of Id. But that's not going to work because my business logic references Id only. Still thinking... I may be stuck...
As a hack, I could leave EntityBase in its original form. Then, in the new DAL, when I perform the ORM, I could just convert the ID of the table to a string.
I suggest to add one more layer then.
For instance, to create a new class like this:
public abstract class CommonEntityBase<T> : NotifyPropertyChangedBase{
public T Id {get;set;}
}
And then, derive your old EntityBase from this class:
public class EntityBase : CommonEntityBase<string>{
//this property is present only in this old implementation
public Guid ETag { get; set; }
}
So now, you can create a new layer and use a base class for that as well:
public class FancyEntityBase : CommonEntityBase<int>{
//No ETag concept here - ad new properties, methods, etc.
}
However, there is a question if you really need to change your primary keys to be integers.
This may result in performance issues when the ORM is used.

Entity Framework 4.1 Loose Coupling on Entities

Need a little help please if anyone can shed some light on this.
I've created a code-first MVC 3 application which I have working fine. I'm refactoring now to remove as much coupling as possible as I want the domain model to be used in various other MVC 3 applications later on. What I have now is a collection of entities which are persisted via a normalised database and they are CRUD-ed through a repository pattern. I have used Ninject to DI the repositories via the controller's constructor and am using models within the MVC 3 project to act as DAOs.
So, within the domain I have an entity called Case that has a foreign key to another case Client that looks like this:
public class Case : ICase
{
[Key]
public int CaseId { get; set; }
public string CaseName { get; set; }
public DateTime DateCreated { get; set; }
public IClient Client { get; set; }
}
Then I have an interface (the interface exists mainly to implement it to the view model to add my data annotations - I know I could add the annotations to the domain object but as I said I want to use this domain model in other applications which will have a different ubiquitious language.
public interface ICase
{
int CaseId { get; set; }
string CaseName { get; set; }
DateTime DateCreated { get; set; }
IClient Client { get; set; }
}
And then I have my view model within the MVC 3 project.
public class CaseModel : ICase
{
[HiddenInput(DisplayValue = false)]
int CaseId { get; set; }
[Required(AllowEmptyStrings = false)]
[MaxLength(100)]
string CaseName { get; set; }
[RegularExpression("")]
DateTime DateCreated { get; set; }
IClient Client { get; set; }
}
So, my first problem is this: changing my foreign key reference for Client to IClient is a new thing, and it returns a null object. When the type was a concrete class it returned fine - I assume this is because EF4.1 tries to create an instance of IClient. Am I totally wrong here or is there a way around this?
My second problem (which may negate my first problem) is am I also doing something wrong by adding data annotations to a view model inheriting the interface of my domain entity? Should I be using model meta data? If so, how do I use meta data in such a way that I can make the data annotations unique to each project without touching the domain?
Thanks!
Caveat: I'm not an expert on EF or MVC3.
We're in the process of building EF Code First entities, and we're not planning on adding interfaces to the entities. Repositories get interfaces. Units of Work get interfaces. Entities don't. Repositories return concrete entities, which are POCOs. Entities may be coupled to related entities. Models and other classes will typically get repository interfaces and/or unit of work interfaces injected in. For testing, we'll just new up some POCO entities and return them from the mock repositories.
We're planning to make the relevant POCO properties virtual so that EF can create proxies.
If you want to decouple a view from concrete entities, I'd first ask what value you expect to gain from that. Is the view going to be reused with different entities? If so, one option would be to use something like AutoMapper to copy the properties over. You'd have to be aware of the immediate access of lazy-load properties, though.

Adding a property for the count of associated entities in Entity Framework Code First

I'm using Code First to write my data layer, then transmitting to a Silverlight front end using RIA services. Since I have to serialize everything, I would like to get some additional information on each entity before sending it across the wire (to reduce load time). In the past I have done this by translating everything to a POCO class that has the additional information. I'm wondering if there's a better way of doing this. To give you an idea, here's my class:
public class District
{
// ... Other properties, not important
public ICollection Installations { get; set; }
//The property I would like to calculate on the fly
[NotMapped]
public int InstallationCount { get; set; }
}
Is there a way to have this property calculate automatically before I send it across the wire? One option would be just to Include the Installation collection, but that adds a lot of bulk (there are about 50 properties on the Installation entity, and potentially hundreds of records per district).
Rather than making InstallationCount an automatic property, just use the get to return the count function of Installations collection.
public class District
{
public virtual ICollection<Installation> Installations { get; set; }
[NotMapped]
public int InstallationCount { get { return Installations.Count; } }
}

Categories

Resources