Problems with EF-Agnostic design consumed by WCF service. - wcf

I am trying to set up EF to work on WCF and keeping the domain class models EF Agnostic.
The code is organized into 3 projects. (I am taking a stab a DDD - I am very new to it but am looking forward t learning more)
Project: QA - Domain Layer. Contains the DataContract models/entities.
References
QA.Data
Project: QA.Data - Data Layer. Contains the context and EDMX (code generation stragtegy = "none")
References
Entity Framework/System.Data.Entity
Project: QA.Repository - Data Access/Repository. Contains the repository classes
References
QA [Domain Layer]
QA.Data [Data Layer]
Entity Frame/System.DataEntity
My understanding is that the domain layer can reference the data layer but the data layer should never reference the domain. The problem that this presents is that my Domain Models/Classes are defined in the Domain layer but the Context which creates and returns them is in the Data layer. In order for my context to know to return a "Widget" object it would need a reference to the Domain layer which defined the "Widget"
My (failed) solution : My solution was to create interfaces for each Domain Model and place them in the data layer. The context would return ... IdbSet ... These interfaces would, in turn, be implemented by the Domain Models, therefore keeping my data layer from directly needing to reference my domain (which causes illegal circular references anyway). The domain models were originally contructed using "ADO.NET DbContext Generator w/WCF Support" T4 templates. This process resulted in the inclusion of the [KnownType(typeof(IWidgetPiece))] at the beginning of of the widget class defin ition. (A Widget has a navigation property ... ICollection ...)
The problem appears when I attempt to access the service, I get the following error
'QA.Data.IWidgetPiece' cannot be added to list of known types since
another type 'System.Object' with the same data contract name
'http://www.w3.org/2001/XMLSchema:anyType' is already present. If
there are different collections of a particular type - for example,
List and Test[], they cannot both be added as known types.
Consider specifying only one of these types for addition to the known
types list.
I can change these to the concrete implementations ... [KnownType(typeof(WidgetPiece))] ... but I continue to get this error because the navigation property they are referring to is still returning an IWidgetPiece interface type which it MUST do in order to satify the interface implementation.
I am trying to figure out how to keep things appropriately divided and still have the context returning what it should. the context returning Interfaces still doesn't "sit" right with me for this and other reasons but I cannot think of another way to do this, and even this is presenting the aforementioned issue. HELP!
Some code to hopefully clarify my previous ramblings ...
namespace QA.Data
{
public interface IWidgetPiece
{
String ID { get; set; }
}
public interface IWidget
{
String ID { get; set; }
ICollection<IWidgetPiece> Pieces;
}
public partial class WidgetEntities : DbContext
{
IDbSet<IWidget> Widgets { get; set; }
IDbSet<IWidgetPiece> WidgetPieces { get; set; }
}
}
namespace QA
{
[KnownType(typeof(IWidgetPiece))]
// [KnownType(typeof(WidgetPiece))]
[DataContract(IsReference = true)]
public partial class Widget : QA.Data.IWidget
{
[DataMember]
public String ID { get; set; }
[DataMember]
public virtual ICollection<IWidgetPiece> Pieces { get; set; }
}
[DataContract(IsReference = true)]
public partial class WidgetPiece : QA.Data.IWidgetPiece
{
[DataMember]
public string ID { get; set; }
}
}
namespace QA.Repository
{
public class WidgetRepository
{
public List<Widget> GetWidgetbyID(String sId)
{
WidgetEntities context = new WidgetEntities();
List<IWidget> objs = context.Widgets.Where(b => b.ID == "78").ToList();
List<Widget> widgetList = new List<Widget>();
foreach (var iwidget in widgetList)
widgetList((Widget)iwidget);
return widgetList;
}
}
}

Do you really want / need two separate models i.e. your data access layer model (edmx) and your "real" domain model? The whole point of an ORM framework like EF is so you can map your domain model to your database tables, using mappings between the physical (database) conceptual model.
Since EF4.1, you can construct your domain model and then in your data access layer map that to your database directly using a fluent API. You can also elect to reverse-engineer your POCO domain model from a database if you want to quickly get up an running.
It just seems a bit of unnecessary complexity to create an entire EF class model, only to then have to map it again into another class model (which will most likely be fairly close to the EF-generated one).

Related

Problem with Include() EntityFramework Core with blazor server side [duplicate]

I had seen some books(e.g programming entity framework code first Julia Lerman) define their domain classes (POCO) with no initialization of the navigation properties like:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Address> Address { get; set; }
public virtual License License { get; set; }
}
some other books or tools (e.g Entity Framework Power Tools) when generates POCOs initializes the navigation properties of the the class, like:
public class User
{
public User()
{
this.Addresses = new IList<Address>();
this.License = new License();
}
public int Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
public virtual License License { get; set; }
}
Q1: Which one is better? why? Pros and Cons?
Edit:
public class License
{
public License()
{
this.User = new User();
}
public int Id { get; set; }
public string Key { get; set; }
public DateTime Expirtion { get; set; }
public virtual User User { get; set; }
}
Q2: In second approach there would be stack overflow if the `License` class has a reference to `User` class too. It means we should have one-way reference.(?) How we should decide which one of the navigation properties should be removed?
Collections: It doesn't matter.
There is a distinct difference between collections and references as navigation properties. A reference is an entity. A collections contains entities. This means that initializing a collection is meaningless in terms of business logic: it does not define an association between entities. Setting a reference does.
So it's purely a matter of preference whether or not, or how, you initialize embedded lists.
As for the "how", some people prefer lazy initialization:
private ICollection<Address> _addresses;
public virtual ICollection<Address> Addresses
{
get { return this._addresses ?? (this._addresses = new HashSet<Address>());
}
It prevents null reference exceptions, so it facilitates unit testing and manipulating the collection, but it also prevents unnecessary initialization. The latter may make a difference when a class has relatively many collections. The downside is that it takes relatively much plumbing, esp. when compared to auto properties without initialization. Also, the advent of the null-propagation operator in C# has made it less urgent to initialize collection properties.
...unless explicit loading is applied
The only thing is that initializing collections makes it hard to check whether or not a collection was loaded by Entity Framework. If a collection is initialized, a statement like...
var users = context.Users.ToList();
...will create User objects having empty, not-null Addresses collections (lazy loading aside). Checking whether the collection is loaded requires code like...
var user = users.First();
var isLoaded = context.Entry(user).Collection(c => c.Addresses).IsLoaded;
If the collection is not initialized a simple null check will do. So when selective explicit loading is an important part of your coding practice, i.e. ...
if (/*check collection isn't loaded*/)
context.Entry(user).Collection(c => c.Addresses).Load();
...it may be more convenient not to initialize collection properties.
Reference properties: Don't
Reference properties are entities, so assigning an empty object to them is meaningful.
Worse, if you initiate them in the constructor, EF won't overwrite them when materializing your object or by lazy loading. They will always have their initial values until you actively replace them. Worse still, you may even end up saving empty entities in the database!
And there's another effect: relationship fixup won't occcur. Relationship fixup is the process by which EF connects all entities in the context by their navigation properties. When a User and a Licence are loaded separately, still User.License will be populated and vice versa. Unless of course, if License was initialized in the constructor. This is also true for 1:n associations. If Address would initialize a User in its constructor, User.Addresses would not be populated!
Entity Framework core
Relationship fixup in Entity Framework core (2.1 at the time of writing) isn't affected by initialized reference navigation properties in constructors. That is, when users and addresses are pulled from the database separately, the navigation properties are populated.
However, lazy loading does not overwrite initialized reference navigation properties.
In EF-core 3, initializing a reference navigation property prevents Include from working properly.
So, in conclusion, also in EF-core, initializing reference navigation properties in constructors may cause trouble. Don't do it. It doesn't make sense anyway.
In all my projects I follow the rule - "Collections should not be null. They are either empty or have values."
First example is possible to have when creation of these entities is responsibility of third-part code (e.g. ORM) and you are working on a short-time project.
Second example is better, since
you are sure that entity has all properties set
you avoid silly NullReferenceException
you make consumers of your code happier
People, who practice Domain-Driven Design, expose collections as read-only and avoid setters on them. (see What is the best practice for readonly lists in NHibernate)
Q1: Which one is better? why? Pros and Cons?
It is better to expose not-null colections since you avoid additional checks in your code (e.g. Addresses). It is a good contract to have in your codebase. But it os OK for me to expose nullable reference to single entity (e.g. License)
Q2: In second approach there would be stack overflow if the License class has a reference to User class too. It means we should have one-way reference.(?) How we should decide which one of the navigation properties should be removed?
When I developed data mapper pattern by myself I tryed to avoid bidirectional references and had reference from child to parent very rarely.
When I use ORMs it is easy to have bidirectional references.
When it is needed to build test-entity for my unit-tests with bidirectional reference set I follow the following steps:
I build parent entity with emty children collection.
Then I add evey child with reference to parent entity into children collection.
Insted of having parameterless constructor in License type I would make user property required.
public class License
{
public License(User user)
{
this.User = user;
}
public int Id { get; set; }
public string Key { get; set; }
public DateTime Expirtion { get; set; }
public virtual User User { get; set; }
}
It's redundant to new the list, since your POCO is depending on Lazy Loading.
Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook.
If you would remove the virtual modifier, then you would turn off lazy loading, and in that case your code no longer would work (because nothing would initialize the list).
Note that Lazy Loading is a feature supported by entity framework, if you create the class outside the context of a DbContext, then the depending code would obviously suffer from a NullReferenceException
HTH
The other answers fully answer the question, but I'd like to add something since this question is still relevant and comes up in google searches.
When you use the "code first model from database" wizard in Visual Studio all collections are initialized like so:
public partial class SomeEntity
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public SomeEntity()
{
OtherEntities = new HashSet<OtherEntity>();
}
public int Id { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OtherEntity> OtherEntities { get; set; }
}
I tend to take wizard output as basically being an official recommendation from Microsoft, hence why I'm adding to this five-year-old question. Therefore, I'd initialize all collections as HashSets.
And personally, I think it'd be pretty slick to tweak the above to take advantage of C# 6.0's auto-property initializers:
public virtual ICollection<OtherEntity> OtherEntities { get; set; } = new HashSet<OtherEntity>();
Q1: Which one is better? why? Pros and Cons?
The second variant when virtual properties are set inside an entity constructor has a definite problem which is called "Virtual member call in a constructor".
As for the first variant with no initialization of navigation properties, there are 2 situations depending on who / what creates an object:
Entity framework creates an object
Code consumer creates an object
The first variant is perfectly valid when Entity Framework creates a object,
but can fail when a code consumer creates an object.
The solution to ensure a code consumer always creates a valid object is to use a static factory method:
Make default constructor protected. Entity Framework is fine to work with protected constructors.
Add a static factory method that creates an empty object, e.g. a User object, sets all properties, e.g. Addresses and License, after creation and returns a fully constructed User object
This way Entity Framework uses a protected default constructor to create a valid object from data obtained from some data source and code consumer uses a static factory method to create a valid object.
I use the answer from this Why is my Entity Framework Code First proxy collection null and why can't I set it?
Had problems with constructor initilization. Only reason I do this is to make test code easier. Making sure collection is never null saves me constantly initialising in tests etc

Implement Repository Pattern in Asp.Net MVC with SOA architecture

We have starting new project in our company. We finalize the architecture as follows
There are 5 different project as follows
1) BusinessEntities(Class Library) which contains DataContract as follows
[DataContract]
public class Cities
{
/// <summary>
/// Gets or sets City Id
/// </summary>
[DataMember]
public int Id { get; set; }
/// <summary>
/// Gets or sets City name
/// </summary>
[DataMember]
[Display(Name = "CityName", ResourceType = typeof(DisplayMessage))]
[Required(ErrorMessageResourceName = "CityName", ErrorMessageResourceType = typeof(ErrorMessage))]
[RegularExpression(#"[a-zA-Z ]*", ErrorMessageResourceName = "CityNameAlphabates", ErrorMessageResourceType = typeof(ErrorMessage))]
[StringLength(50, ErrorMessageResourceName = "CityNameLength", ErrorMessageResourceType = typeof(ErrorMessage))]
public string Name { get; set; }
}
2) Interface which contains
[ServiceContract]
public interface ICity : IService<CityViewModel>
{
[OperationContract]
Status Add(Cities entity);
}
3) DAL which contains implementation of WCF service
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class City : ICity
{
public Status Add(Cities entity)
{
//Insert Logic goes here
}
}
4) Webcomponent which call the WCF service
public class City
{
public static Status Add(Cities entity)
{
using (var service = new WcfServiceProvider<ICity>())
{
return service.GetProxy().Add(entity);
}
}
}
5) UI (Asp.Net MVC Project) which call webcomponent to access service
City.Add(entity);
Now we finalize this structure. But the problem is how to use Repository Pattern for Unit Testing? Is it possible to use repository pattern on this structure if yes how? Or is there any other pattern we have to use?
I recommend that you read about seperation of concerns. Right now you are using your business object as DTO and BO. That effectivly couples your WCF service with your domain layer AND with the UI layer.
That means that version control will be impossible. If you want to do any change in the UI or in the DL you have to make sure that all changes are made in both layers as the UI won't be able to talk with the BL otherwise.
It's much better to have dedicated DTOs since you then can handle versioning issues a lot easier (like default values or a newly introduced property etc).
Your naming does not make sense. Your Cities class contains ONE city, right? Why don't you name it City.
[ServiceContract]
public interface ICity : IService<CityViewModel>
{
[OperationContract]
Status Add(Cities entity);
}
Can you explain what the service definition is? I don't see the relation between the view model and the DTO. Same thing goes here. The name ICity is misleading. If it's a repository name it as such. Most of us use the City name to point out the object that we work with and use other names like ICityService or ICityRepository to point out the access technologies.
Now to the real question:
But the problem is how to use Repository Pattern for Unit Testing?
You don't.
The only responsibilty of repositories is to load and store data in the data source. You can of course mock the DbConnection etc. But that doesn't guarantee anything at all since the repositories is effectivly coupled to the data source. If you use mocks you'll still get failures from incorrect SQL queries, invalid column types, incorrect table relations etc.
Hence if you truly want to make sure that the repositories work you have to query a database.

EF4 and intentionally returning only *some* of the properties of an entity

Folks, I know I didn't phrase that title very well, but here's the scenario.
I have a WinForm UI tier, and a WCF middle tier, serving up my EF4 entity objects, which are (of course) mapped to my database tables. Everything works fine.
One of my objects is the Client - and in the Client db table are three varbinary(max) fields for PDF documents. So my entity object has three Byte() properties, one for each document.
But when I load up an initial grid listing the Clients, it's going to drag ALL that PDF data from the MT - making a much bigger payload than I generally need.
With DataSets, I'd write my SQL to not include the PDF binary - but I'd include a Boolean flag field for each to indicate whether there IS one to download if the user wants it. Then I'd load the PDFs via a separate call as needed.
With EF4 - what's the best pattern for this?
First, I'm thinking to put the documents into a child-table/child-objects, so I don't pull it across the tier with the Client. One problem solved.
Second, I suppose I could use partial classes to extend my Client entity object to have the three Boolean properties I want.
Am I on the right track?
I think you have three options:
1) Create a custom class which you project the properties you want into:
public class MySpecialSelection
{
public int ID { get; set; }
public string Name { get; set; }
// more
public bool HasPDFDoc1 { get; set; }
public bool HasPDFDoc2 { get; set; }
public bool HasPDFDoc3 { get; set; }
}
using (var context = new MyContext())
{
var mySpecialSelectionList = context.MyEntities.Where(...some predicate...)
.Select(e => new MySpecialSelection
{
ID = e.ID,
Name = e.Name,
// ...
HasPdfDoc1 = (e.PdfDoc1 != null),
HasPdfDoc2 = (e.PdfDoc2 != null),
HasPdfDoc3 = (e.PdfDoc3 != null),
}).ToList();
// ...
}
Instead of a "named" object you can also project into anonymous types.
Note: This doesn't attach any full model entity to the context, so you won't have any change tracking of entities.
2) Table splitting: It means that you split your single entity into two separate classes which are related by a navigation property. You can map then both entities to a single table in the database. It allows you to load the navigation properties (for instance the binary fields) on request (by lazy, eager or explicite loading). Details about this for EF4.0 are here and for EF4.1 here.
3) Your own proposal: Create separate tables and separate entities which are linked by navigation properties and FK constraints.

Do I have to implement Add/Delete methods in my NHibernate entities?

This is a sample from the Fluent NHibernate website:
Compared to the Entitiy Framework I have ADD methods in my POCO in this code sample using NHibernate. With the EF I did context.Add or context.AddObject etc... the context had the methods to put one entity into the others entity collection!
Do I really have to implement Add/Delete/Update methods (I do not mean the real database CRUD operations!) in a NHibernate entity ?
public class Store
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
public virtual IList<Employee> Staff { get; set; }
public Store()
{
Products = new List<Product>();
Staff = new List<Employee>();
}
public virtual void AddProduct(Product product)
{
product.StoresStockedIn.Add(this);
Products.Add(product);
}
public virtual void AddEmployee(Employee employee)
{
employee.Store = this;
Staff.Add(employee);
}
}
You don't have to do this for nhibernate, you have to do this for keep in-memory consistence and not repeat yourself.
Consistence in memory
If you have a two way relationship, lets say Order has Lines, and Line as a relationship to order. You don't want to have a reference from one side and not from the other.
If you just do:
order.Lines.Add(line);
You have made a reference from Order to Line, but Line.Order property remains null. So your in-memory instances are not consistent.
Don't Repeat Yourself
You can use the following code :
order.Lines.Add(line);
line.Order = order;
but you will be repeating yourself, so it is better to put this code in only one place, and the best place is as order.AddLine(..).
You don't have to. You could just call SomeStore.Products.Add(someProduct) directly from outside of your entity. But it's often good practice to make the collections 'read-only' from a public perspective, and using an add method in the entity for adding items.
One benefit of this is that you can put additional logic in there. For instance in your store example, you could set a 'storesStockedIn' collection (if there was such a thing) in the same method, and so keep all the logic about to creating that relationship in one place.
This isn't really a NHibernate thing, but rather an OOP thing. (Although I'm not familiar with EF - maybe it automates some of this for you). The design decisions are exactly the same as if it was just an unpersisted poco (without NHibernate).

How to simply map an NHibernate ISet to IList using AutoMapper

I'm trying to use AutoMapper to map from DTO's to my Domain.
My DTO's might look like this:
public class MyDTO
{
public string Name { get; set; }
public bool OtherProperty { get; set; }
public ChildDTO[] Children { get; set;}
}
public class ChildDTO
{
public string OtherName { get; set; }
}
My Domain objects like this:
public class MyDomain
{
public string Name { get; set; }
public bool OtherProperty { get; set; }
public ISet<ChildDomain> Children { get; set; }
}
public class ChildDomain
{
public string OtherName { get; set; }
}
How would I setup AutoMapper to be able to map from these Array's to Set's. It seems like AutoMapper is taking the Array's and converting them into IList's then failing on conversion to ISet.
Here's the exception
Unable to cast object of type 'System.Collections.Generic.List`1[DataTranser.ChildDTO]' to type 'Iesi.Collections.Generic.ISet`1[Domain.ChildDomain]'.
I'm hoping to find a simple generic way to do this so that I can minimize the infrastructure needed to map from DTO's to Domain. Any help is greatly appreciated.
UPDATE:
So then how would I model MyDomain -> ChildDomain without ending up with an anemic domain model? I understand that without business logic in MyDomain or ChildDomain the domain model is currently anemic, but the goal was to add business logic in as we move forward. I just want to ensure that my View Model can be translated into the domain model and persisted.
What would you suggest for this scenario, moving from a simple mapping between view and domain and later adding in business rules?
Thanks again for your help.
If your persistence layer is simple, using UseDestinationValue() will tell AutoMapper to not replace the underlying collection:
ForMember(dest => dest.Children, opt => opt.UseDestinationValue())
However, if it's not simple, we just do the updating manually back into the domain. The logic generally gets more complex to update the domain model. Doing reverse mapping puts constraints on the shape of your domain model, which you might not want.
The answer:
You have to create your own IObjectMapper to map a custom collection like ISet
Create your own configuration instance with all the standard
objectmappers and your new
setobjectmapper.
Use an IMappingEngine instance created with the configuration with
your own objectmapper instead of the
static AutoMapper.Mapper class.
Some remarks:
It's easy to configure the IMappingEngine construction in a inversion of control container.
The source of automapper itself might help you with creating the IObjectMapper implementation.
You are using automapper on the opposite way for what it is designed for: It's designed to map complex objects to simple objects. You try to map a simple DTO to a complex entity. (This does not mean that what you want is hard to do with automapper, but you might get different problems in the future)
You are using the anemic domain model anti pattern. Domain should hold all the business logic, so it should not expose a complex collection like ISet (and no public setters for collections at all)