EF Code first problem - related entity not loaded - entity-framework

this is really annoying
I have something like this:
class Person {
..properties id, name etc..
}
class Task {
..properties id, name etc..
Person Moderator {get;set}
}
public class DataModel : DbContext {
public DbSet<Task> Tasks { get; set; }
public DbSet<Person> People { get; set; }
}
I can then create new tasks and add People objects to the task and save, and I can see the data correctly saved in the sql backend - each Task saved has the correct Person id saved
with it and the Person with that id is saved back as well.
But when I try and get back a task, the person object is always null.
using (DataModel db = new DataModel()) {
Task t = db.Tasks.SingleOrDefault(p => p.Id == 22);
assert(t.Name.Lenght>0)
assert(t.Moderator != null) // always null!!!!!!
....
}
What do I have to do to get the whole object graph bought back? Do I have to do a join in the SingleorDefault call? seems a bit wrong somehow.
Did I mention this is really annoying.
TIA,

Two options for you. By default the code first / dbContext model returns a proxy object that derives from your model (this is important to understand when you run into JSON serialization issues). The proxy object uses lazy loading of associations but only under certain circumstances. The Moderator property has to be declared as virtual so that the proxy can override it and do the lazy loading for you.
However lazy loading can create a problem called Select N+1. If in most cases you only need the Task and not the Moderator, this won't be a problem. However if you frequently display a list of tasks and their associated moderators, you will effectively have to run an extra round trip to the database for every task in that list in addition to the 1 for the original list(e.g. for a list of 100 tasks you would do 101 queries to display the tasks and their moderators).
To get around this, EF provides the Include operator, this forces the relation to load. Use it as such
Task t = db.Tasks.Include(t=>t.Moderator).SingleOrDefault(p => p.Id ==
22);
Hope this helps.

You have lazy loading turned off for your Moderator property, so it will only be loaded if you explicitly do so using Load().
You can force EF to eagerly load your related Person entity by using the Include() method in your query like this:
Task t = db.Tasks.Include(x => x.Moderator).SingleOrDefault(p => p.Id == 22)
There is a pretty good overview in this article.

Related

How to deal with deleted event classes in event sourcing

I am trying to implement a pure event sourced service to see where I will get problems. Now I found a problem that I can not solve so far, so I would like to open a discussion about it.
Given the following aggregate:
class User
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public void Apply(UserNameChangedEvent domainEvent)
{
Name = domainEvent.NewName;
}
public void Apply(UserCreatedEvent domainEvent)
{
Name = domainEvent.Name;
Id = domainEvent.Id;
}
}
and those Domain Events
class UserCreatedEvent
{
public string NewName { get; }
public Guid Id { get; }
public UserCreatedEvent(string newName, Guid id)
{
NewName = newName;
Id = id;
}
}
class UserNameChangedEvent
{
public string NewName { get; }
public UserNameChangedEvent(string newName)
{
NewName = newName;
}
}
Lets say I create a user and change its name to "Peter" afterwards, then I have a UserCretedEvent and a UserChangedNameEvent persisted in my EventStore. Now the business says that changing a name is no longer possible and therefore I would remove the class UserChangedNameEvent and the function that handles it. But now I have the problem that I can not recreate the aggregate in its correct state, which would be with the name "Peter".
Of course I could start hacking around and mark the function and class as deprecated, so I could keep using it, but I might end up with a lot of event classes afterwards and this will be a nightmare to keep track of. I also heard you might create a new event that persists the change in the domain, but that also seems very hacky to me and not a very good style, as this is no domain event in my point of view.
So the question is, how do I deal the best with changes like this?
edit: just to clarify: I do not want to delete any event, just the class and the function where I use it, as the requirement is different now.
THE resource for questions related to changes in event schemas is Versioning in an Event Sourced System, by Greg Young.
So the question is, how do I deal the best with changes like this?
It depends on the real problem that you are trying to solve.
If the requirement is that users aren't allowed to change their names in the future, then you take away the logic in the domain model that creates new UserNameChangedEvents, but leave behind the correct processing where the events do appear.
If the requirement is that changes to user names should be ignored, then you also take the Apply(UserNameChanged) handler and turn it into a NoOp, just as you would for any other unrecognized event.
If the requirement is that information about name changes should be destroyed, then you migrate your event store to a new schema, that no longer includes the UserNameChanged event.
It may help to think through how you would solve the problem if you were storing your state in an RDBMS: is it enough to ignore the User Name column? do you need to delete the column? Do you need to (somehow) restore value in a column to a previously written value?
Knowing the problem in a traditional database that is analogous to the problem you want to solve in the event store should help identify the appropriate solution.
Also: pay attention to whether or not your domain model is the system of record for the data that needs changed, or if instead you are caching a representation of information published by a different authority.
Events captured facts about the system. If User name was changed at some point, it is a fact. Future business rule changes cannot affect past facts.
So you should not remove UserNameChanged events, and all associated handlers, events are there, and you should not rewrite past history.
In CQRS app, events are generated by command handlers. So this is a place where you specify business requirements. "Now the business says that changing a name is no longer possible" means that ChangeName command is no longer available: you can simply remove it, or just throw an error saying that you cannot change names anymore.

Why are foreign keys in EF Code First marked as virtual?

public virtual Student Student {get; set;}
Why does a foreign key constraint need to be marked as virtual? I've seen examples with both virtual and lacking virtual. Does it matter?
By looking at this : https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx, and the link that has been provided in the comments by #Shoes.
I would say this :
1. if you declare your property virtual :
Your virtual property (by default) won't be loaded right away when querying the main object. It will be retreive from the database ONLY if you try to access it, or access one of it's components.
And this is called lazy loading.
2. if you declare it non-virtual :
Your property will (by default) be loaded right away along with all the other property in your main entity. This means your property will be ready to access : it has already been retreived. Entity won't have to query again the database because you access this property.
This is called eagerly loading.
My opinion :
More often i choose eagerly loading (non-virtual) because most of the time, i need every property of every entity to be used along without having to query back (faster in the case you really want everything quick) but if you access this property only once in a while (your not listing anything) and you want more often just the rest of the informations exept THIS one, then make it virtual so this property won't slow down the rest of the query just for a few access.
Hope this was clear...
Exemples :
Where I would NOT use virtual (Eagerly) :
foreach(var line in query)
{
var v = line.NotVirtual; // I access the property for every line
}
Where I would use virtual or lazy loading :
foreach(var line in query)
{
if(line.ID == 509) // because of this condition
var v = line.Virtual; // I access the property only once in a while
}
one last thing :
If you don't query over 1 000 lines of a database, then whatever you choose won't have a big effect. Also, you can declare these property virtual and if you want to test the other way around, you just have to do this (Entity 4.0) :
context.LazyLoadingEnabled = false;
It will cancel the virtual effect.
Edit
For newer versions of EF :
WhateverEntities db = new WhateverEntities()
db.Configuration.LazyLoadingEnabled = false;

EntityFramework with Repository Pattern and no Database

I have a web api project that I'm building on an N-Tier system. Without causing too many changes to the overall system, I will not be touching the data server that has access to the database. Instead, I'm using .NET remoting to create a tcp channel that will allow me to send requests to the data server, which will then query the database and send back a response object.
On my application, I would like to use entity framework to create my datacontexts (unit of work), then create a repository pattern that interfaces with those contexts, which will be called by the web api project that I created.
However, I'm having problems with entity framework as it requires me to have a connection with the database. Is there anyway I can create a full entity framework project without any sqlconnections to the database? I just need dbcontexts, which I will be mapping my response objects and I figure that EF would do what I needed (ie help with design, and team collabs, and provide a nice graphical designer); but it throws an error insisting that I need a connection string.
I've been searching high and low for tutorials where a database is not needed, nor any sql connection string (this means no localdb either).
Okay as promised, I have 3 solutions for this. I personally went with #3.
Note: Whenever there is a repository pattern present, and "datacontext" is used, this is interpreted as your UnitOfWork.
Solution 1: Create singletons to represent your datacontext.
http://www.breezejs.com/samples/nodb
I found this idea after going to BreezeJS.com's website and checked out their samples. They have a sample called NoDb, which allows them to create a singleton, which can create an item and a list of items, and a method to populate the datacontext. You create singletons that would lock a space in memory to prevent any kind of thread conflicts. Here is a tid bit of the code:
//generates singleton
public class TodoContext
{
static TodoContext{ }
private TodoContext() { }
public static TodoContext Instance
{
get
{
if (!__instance._initialized)
{
__instance.PopulateWithSampleData();
__instance._initialized = true;
}
return __instance;
}
}
public void PopulateWithSampleData()
{
var newList = new TodoItem { Title = "Before work"};
AddTodoList(newList);
var listId = newList.TodoListId;
var newItem = new TodoItem {
TodoListId = listId, Title = "Make coffee", IsDone = false };
AddTodoItem(newItem);
newItem = new TodoItem {
TodoListId = listId, Title = "Turn heater off", IsDone = false };
AddTodoItem(newItem);
}
//SaveChanges(), SaveTodoList(), AddTodoItem, etc.
{ ... }
private static readonly Object __lock = new Object();
private static readonly TodoContext __instance = new TodoContext();
private bool _initialized;
private readonly List<TodoItem> _todoLists = new List<TodoItem>();
private readonly List<KeyMapping> _keyMappings = new List<KeyMapping>();
}
There's a repository included which directs how to save the context and what needs to be done before the context is saved. It also allows the list of items to be queryable.
Problem I had with this:
I felt like there was higher maintenance when creating new datacontexts. If I have StateContext, CityContext, CountryContext, the overhead of creating them would be too great. I'd have problems trying to wrap my head around relating them to each other as well. Plus I'm not too sure how many people out there who agree with using singletons. I've read articles that we should avoid singletons at all costs. I'm more concerns about anyone who'd be reading this much code.
Solution 2: Override the Seed() for DropCreateDatabaseAlways
http://www.itorian.com/2012/10/entity-frameworks-database-seed-method.html
For this trick, you have to create a class called SampleDatastoreInitializer that inherits from System.Data.Entity.DropCreateDatabaseAlways where T is the datacontext, which has a reference to a collection of your POCO model.
public class State
{
[Key()]
public string Abbr{ get; set; }
public string Name{ get; set; }
}
public class StateContext : DbContext
{
public virtual IDbSet<State> States { get; set; }
}
public class SampleDatastoreInitializer : DropCreateDatabaseAlways<StateContext>
{
protected override void Seed (StateContext context)
{
var states = new List<State>
{
new State { Abbr = "NY", Name = "New York" },
new State { Abbr = "CA", Name = "California" },
new State { Abbr = "AL", Name = "Alabama" },
new State { Abbr = "Tx", Name = "Texas" },
};
states.ForEach(s => context.States.Add(s));
context.SaveChanges();
}
}
This will actually embed the data in a cache, the DropCreateDatabaseAlways means that it will drop the cache and recreate it no matter what. If you use some other means of IDatabaseInitializer, and your model has a unique key, you might get an exception error, where you run it the first time, it works, but run it again and again, it will fail because you're violating the constraints of primary key (since you're adding duplicate rows).
Problem I had with this:
This seems like it should only be used to provide sample data when you're testing the application, not for production level. Plus I'd have to continously create a new initializer for each context, which plays a similar problem noted in solution 1 of maintainability. There is nothing automatic happening here. But if you want a way to inject sample code without hooking up to a database, this is a great solution.
Solution 3: Entity framework with Repository (In-memory persistence)
I got this solution from this website:
http://www.roelvanlisdonk.nl/?p=2827
He first sets up an edmx file, using EF5 and the code generator templates for EF5 dbcontexts you can get from VS extension libraries.
He first uses the edmx to create the contexts and changes the tt templates to bind to the repository class he made, so that the repository will keep track of the datacontext, and provide the options of querying and accessing the data through the repository; in his website though he calls the repository as MemoryPersistenceDbSet.
The templates he modified will be used to create datacontexts that will bind to an interface (IEntity) shared by all. Doing it this way is nice because you are establishing a Dependency Injection, so that you can add any entity you want through the T4 templates, and there'd be no complaints.
Advantage of this solution:
Wrapping up the edmx in repository pattern allows you to leverage the n-tier architecture, so that any changes done to the backend won't affect the front end, and allows you to separate the interface between the front end and backend so there are no coupled dependencies. So maybe later on, I can replace my edmx with petapoco, or massive, or some other ORM, or switch from in-memory persistence to fetching data from a database.
I followed everything exactly as explained. I made one modification though:
In the t4 template for .Context.tt, where DbSetInConstructor is added, I had the code written like this:
public string DbSetInConstructor(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
“this.{1} = new BaseRepository();”,
_typeMapper.GetTypeName(entitySet.ElementType), entitySet);
}
Because in my case I had the entityset = Persons and entityname = Person. So there’d be discrepancy. But this should cover all bases.
Final step:
So whether you picked solution 1, 2, or 3. You have a method to automatically populate your application. In these cases, the stubs are embedded in the code. In my case, what I've done is have my web server (containing my front end app), contact my data server, have the data server query the database. The data server will receive a dataset, serialize it, and pass it back to the web server. The web server will take that dataset, deserialize it, and auto-map to an object collection (list, or enumberable, or objectcollection, etc).
I would post the solutions more fully but there's way too much detail between all 3 of these solutions. Hopefully these solutions would point anyone in the right direction.
Dependency Injection
If anyone wants some information about how to allow DI to api controllers, Peter Provost provides a very useful blog that explains how to do it. He does a very very good job.
http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/
few more helpful links of repository wrapping up edmx:
http://blogs.msdn.com/b/wriju/archive/2013/08/23/using-repository-pattern-in-entity-framework.aspx
http://www.codeproject.com/Articles/688929/Repository-Pattern-and-Unit-of

Getting a navigation property populated when using a parent class to fetch

I am using a membership provider that specifies required fields in user such as username and password. You can then inherit this user class to create your own user with any other fields you need.
I added an account like so
public Account AdminAccount { get; set; }
when i now get my user using the membershipprovider it does this:
return _context.Set<TUser>().SingleOrDefault(u => u.Username == username);
The class definition for this membership class looks like so
public class FlexMembershipUserStore<TUser>
: IFlexUserStore
where TUser: class, IFlexMembershipUser, new()
So I send in my user class when creating it, and the class knows about Tuser as a IFlexMembershipUser.
However IFlexMembershipUser does not have my AdminAccount property, only my class that inherits from IFlexMembershipUser has that.
And so when I fetch my user even tho he in the database has a field called AdminAccount_Id which is set correctly I only get AdminAccount to be null.
I see the problem of course with the membership only seeing IFlexMembershipUser and my property not existing on that class but other scalar values are read in properly.
Is there anything I can do about it.
In this particular case I can make the account keep track of it's admins as a user list instead. So I can solve this that way but I am still curious if this can be solved otherwise.
The issue here is that EF only loads things you tell it to for performance reasons. You have two options for loading the remote nav properties, Eager loading (my prefered) or lazy loading.
With Eager loading you tell EF at query time you are interested in the specific nav property and it will go ahead and load it for you. To do this:
using System.Data.Entity;
....
_context.Set<TUser>().Include(u=>u.AdminAccount).SingleOrDefault(u => u.Username == username);

Unit testing EF - how to extract EF code out from BL?

I have read so much (dozens of posts) about one thing:
How to unit test business logic code that has Entity Framework code in it.
I have a WCF service with 3 layers :
Service Layer
Business Logic Layer
Data Access Layer
My business logic uses the DbContext for all the database operations.
All my entities are now POCOs (used to be ObjectContext, but I changed that).
I have read Ladislav Mrnka's answer here and here on the reasons why we should not mock \ fake the DbContext.
He said:
"That is the reason why I believe that code dealing with context / Linq-to-entities should be covered with integration tests and work against the real database."
and:
"Sure, your approach works in some cases but unit testing strategy must work in all cases - to make it work you must move EF and IQueryable completely from your tested method."
My question is - how do you achieve this ???
public class TaskManager
{
public void UpdateTaskStatus(
Guid loggedInUserId,
Guid clientId,
Guid taskId,
Guid chosenOptionId,
Boolean isTaskCompleted,
String notes,
Byte[] rowVersion
)
{
using (TransactionScope ts = new TransactionScope())
{
using (CloseDBEntities entities = new CloseDBEntities())
{
User currentUser = entities.Users.SingleOrDefault(us => us.Id == loggedInUserId);
if (currentUser == null)
throw new Exception("Logged user does not exist in the system.");
// Locate the task that is attached to this client
ClientTaskStatus taskStatus = entities.ClientTaskStatuses.SingleOrDefault(p => p.TaskId == taskId && p.Visit.ClientId == clientId);
if (taskStatus == null)
throw new Exception("Could not find this task for the client in the database.");
if (taskStatus.Visit.CustomerRepId.HasValue == false)
throw new Exception("No customer rep is assigned to the client yet.");
TaskOption option = entities.TaskOptions.SingleOrDefault(op => op.Id == optionId);
if (option == null)
throw new Exception("The chosen option was not found in the database.");
if (taskStatus.RowVersion != rowVersion)
throw new Exception("The task was updated by someone else. Please refresh the information and try again.");
taskStatus.ChosenOptionId = optionId;
taskStatus.IsCompleted = isTaskCompleted;
taskStatus.Notes = notes;
// Save changes to database
entities.SaveChanges();
}
// Complete the transaction scope
ts.Complete();
}
}
}
In the code attached there is a demonstration of a function from my business logic.
The function has several 'trips' to the database.
I don't understand how exactly I can strip the EF code from this function out to a separate assembly, so that I am able to unit test this function (by injecting some fake data instead of the EF data), and integrate test the assembly that contains the 'EF functions'.
Can Ladislav or anyone else help out?
[Edit]
Here is another example of code from my business logic, I don't understand how I can 'move the EF and IQueryable code' out from my tested method :
public List<UserDto> GetUsersByFilters(
String ssn,
List<Guid> orderIds,
List<MaritalStatusEnum> maritalStatuses,
String name,
int age
)
{
using (MyProjEntities entities = new MyProjEntities())
{
IQueryable<User> users = entities.Users;
// Filter By SSN (check if the user's ssn matches)
if (String.IsNullOrEmusy(ssn) == false)
users = users.Where(us => us.SSN == ssn);
// Filter By Orders (check fi the user has all the orders in the list)
if (orderIds != null)
users = users.Where(us => UserContainsAllOrders(us, orderIds));
// Filter By Marital Status (check if the user has a marital status that is in the filter list)
if (maritalStatuses != null)
users = users.Where(pt => maritalStatuses.Contains((MaritalStatusEnum)us.MaritalStatus));
// Filter By Name (check if the user's name matches)
if (String.IsNullOrEmusy(name) == false)
users = users.Where(us => us.name == name);
// Filter By Age (check if the user's age matches)
if (age > 0)
users = users.Where(us => us.Age == age);
return users.ToList();
}
}
private Boolean UserContainsAllOrders(User user, List<Guid> orderIds)
{
return orderIds.All(orderId => user.Orders.Any(order => order.Id == orderId));
}
If you want to unit test your TaskManager class, you should employ the Repository dessign pattern and inject repositories such as UserRepository or ClientTaskStatusRepository into this class. Then instead of constructing CloseDBEntities object you will use these repositories and call their methods, for example:
User currentUser = userRepository.GetUser(loggedInUserId);
ClientTaskStatus taskStatus =
clientTaskStatusRepository.GetTaskStatus(taskId, clientId);
If yout wanto to integration test your TaskManager class, the solution is much more simple. You just need to initialize CloseDBEntities object with a connection string pointing to the test database and that's it. One way how to achieve this is injecting the CloseDBEntities object into the TaskManager class.
You will also need to re-create the test database before each integration test run and populate it with some test data. This can be achieved using Database Initializer.
There are several misunderstandings here.
First: The Repository Pattern. It's not just a facade over DbSet for unit testing! The repository is a pattenr strongly related to Aggregate and Aggreate Root concepts of Domain Driven Design. An aggregate is a set of related entities that should stay consistent to each other. I mean a business consistency, not just only a foreign keys validity. For example: a customer who have made 2 orders should get a 5% discount. So we should somehow manage the consistency between the number of order entities related to a customer entity and a discount property of the customer entity. A node responsible for this is an aggregate root. It is also the only node that should be accessible directly from outside of the aggregate. And the repository is an utility to obtain an aggregate root from some (maybe persistent) storage.
A typical use case is to create a UoW/Transaction/DbContext/WhateverYouNameIt, obtain one aggregate root entity from the repository, call some methods on it or access some other entities by traversing from the root, Commit/SaveChanges/Whatever. Look, how far it differs from yur samples.
Second: The Business Logic. I've already showed you one example: a customer who have made 2 orders should get a 5% discount. In contrary: your second code sample is not a business logic. It's just a query. The responsibility of this code is to obtain some data from the storage. In such a case, the storage technology behind it does matter. So I would recomend integration tests here rather than pretending the storage doesn't matter when interacting with the storage is the sole purpose of this function.
I would also encapsulate that in a Query Object that was already suggested. Then - such a query object could be mocked. Not just DbContext behind it. The whole QO.
The first code sample is a bit better because it probably ivolves some business logic, but that's dificult to identify. Wich leads us to the third problem.
Third: Anemic Domain Model. Your domain doesnt' look very object oriented. You have some dumb entities and transaction scripts over them. With 7 parameters! Thats pure procedural programming.
Moreover, in your UpdateTaskStatus use case - what is the aggregate root? Befere you answer that, the most important question first: what exactly do you want to do? Is that... hmm... marking a current task of a user done when he was visited? Than, maybe there should be a method Visit() inside a Customer Entity? And this method should have something like this.CurrentTaskStatus.IsCompleted = true?
That was just a random guess. If I missed, that would clearly show another issue. The domain model should use the ubiquitous language - something common for the programmer and a business. Your code doesn't have that expressive power that a common language gives. I just don't know what is going on there in UpdateTaskStatus with 7 parameters.
If you place proper expressive methods for performing business operations in your entities that will also enforce you to not use DbContext there at all, as you need your entities to stay persistence ignorant. Then the problem with mocking disappears. You can test the pure business logic without persistence concerns.
So the final word: Reconsider your model first. Make your API expressive by using ubiquitous language first.
PS: Please don't treat me as an authority. I may be completely wrong as I'm just starting to learn DDD.