How Do You Determine the Parent Navigation Properties for an Entity Using Entity Framework - entity-framework-6

I have an Entity Framework 6 POCO and I want to obtain the list of parent navigation properties for that POCO. The code below is how far I have gotten. It seems to work but I can't confirm it will work in all cases.
For example, for POCO Book
class Book
{
int AuthorId;
int BookId;
virtual Author TheAuthor;
}
// Here I pass in the EntityType for the Book POCO.
// This should return new List<string> { "TheAuthor"}
public GetParentNavigationProperties(System.Data.Entity.Core.Metadata.Edm.EntityType entityType)
{
return entityType.NavigationProperties
.Where(np => np.GetDependentProperties().Count() > 0)
.Select(np=>np.Name).ToList();
}
The code above is in part derived from the following post: Programmatically obtain Foreign keys between POCOs in Entity Framework 6

Related

Constructors and Methods on POCO classes with the IRepository Pattern

Is it okay to have a constructor or other non database accessing methods on POCO classes. For example when passing a view model to a controller.
Controller:
public ActionResult SomeMethod(SomeViewModel model)
{
var entity = new SomePocoClasse(model);
// ... then save entity to database
return SomeActionResult
}
Entity:
public SomeClass() {}
public SomeClass(SomeViewModel model)
{
// create itself based on values in model
}
public void Update(SomeViewModel model)
{
// Update itself base on values in model
}
The first entity constructor is for entity framework or regular creation
var entity = new entity
{
// set up properties
};
The second is for creation from SomeViewModel
var entity = new entity(SomeViewModel);
The method is for updating itself from SomeViewModel
var entity = SomeIRepository.Get(id);
entity.Update(SomeViewModel);
Or is the above bad practice which should go some where else.
Yes and no. In general, it's not necessarily bad practice to have a constructor on a POCO. There's any number of reasons why you might want or need that. However, you need to ensure that you maintain a parameterless constructor as well, or you'll cause issues with things like EF which won't know how to properly initialize your POCO class otherwise.
That said, what you're doing here is not good practice. You haven't provided a ton of code, but it appears that what you're doing is passing in the view model to the POCO constructor to set the properties on the POCO with those values. Rather, what you should be doing is pulling the entity fresh from the database and then mapping over any relevant properties on your view model to that entity instance. I supposed what you're doing could be fine solely when creating a new entity, but that means having two separate ways of populating your POCO class with values depending on whether you're creating or editing. That increases complexity and complexity means higher maintenance costs.
Instead, you should either use a library like AutoMapper or create a utility class to handle the mapping:
public static class SomePocoMapper
{
public static SomePoco Map(SomeViewModel model)
{
return Map(model, null);
}
public static SomePoco Map(SomeViewModel model, SomePoco entity)
{
entity = entity ?? new SomePoco();
// map over property values;
return entity;
}
}
Then in your create action:
var entity = SomePocoMapper.Map(model);
And in your edit action:
var entity = // get entity from database
SomePocoMapper.Map(model, entity);

EF model first with MVC Repository Pattern

Attempting to create an MVC project using EF and the Model first approach.
In order to implement it in a way that the Web and data portions are loosely coupled I'm attempting to implement the repository pattern, but, after reading many articles I'm still trying to grasp what objects my Repository interface should return or how they should bind/map to the 'M' model in my MVC project.
Here's a very simplistic example of what I'm asking.
//Repository Interface
public interface IMemberRepository
{
Member GetById(int id);
IEnumerable<Member> FindByName(string name);
}
//Repository Interface Implementation
public class MemberRepository : IMemberRepository
{
//My DB Context object created by EF
private MyContainer context;
public MemberRepository(MyContainer context)
{
this.context = context;
}
public Member GetById(int id)
{
return context.Members.SingleOrDefault(x => x.Id == id);
}
public IEnumerable<Member> FindByName(string name)
{
return context.Members.Find(x => x.name == name);
}
}
So using Ninject as my DI framework I could call this from my controller as follows:
public class GroupsController : Controller
{
public ViewResult Find(string name)
{
IMemberRepository repo =
ObjectFactory.Instance.CreateInstance<IMemberRepository>();
return repo.FindByName(name);
}
}
At this point I'm just not understanding how my Member object (from the EF model) is supposed to bind/map to my 'MVC' member model object. It seems I must be missing some sort of mapping layer or I'm just completely off track. If I were to reference my EF generated class directly it feels like I'm negating the point of using an interface and DI framework. Any advice or direction at this point would be appreciated.
Your IMemberRepository interface and its implementation MemberRepository look right to me. That is how I structure my database code as well.
Moving to the MVC world, I would create view models which you populate from your data model. This will give you the flexibility of adding any attributes or additional properties that you need in your view.
This would be the workflow:
Fetch object(s) from repository
Populate view model objects with all the data from your repository object(s)
Return the view model to your view from the controller

Creating history table using Entity Framework 4.1

I am working on asp.net MVC 3 application and I am using codeFirst approach. I am trying to create history table or user table, Where I want to keep track of what columns were modified by user. How can I do this using EF Code First.
Do I need to do it after DataContext.savechanges ?
Please suggest.
Thanks.
The DbContext has a method called Entry<T>:
var entity = context.Items.Find(id);
entity.Name = "foobar";
var entry = context.Entry<Item>(entity);
entry will be of type DbEntityEntry<T> and has the properties OriginalValues and CurrentValues.
You could probably write something that will generically inspect these properties to see what has changed and then automatically insert a new record into your history table.
Either that, or use database triggers.
I'm not sure if this is really the "appropiate" way to do it, but this is how its usually done in sql:
Create an extra property version of type int or something.
Because you probably do not want to loop every time, add another property IsLatestVersion of type bool
When an entity is saved, check if the entity already exists. If so, set the entity on IsLatestVersion = false.
Increment the version, and save the changes as new entity.
Sounds to me like you want an a filter that inherits from ActionFilterAttribute. In my case, this is the simplest example that I have. This is my model, notice that the attributes dictate the mapping to the database.
[Table("UserProfile")]
public class UserProfile
{
[Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
In my case, it was as simple as the following, although it was not historical:
public sealed class UsersContext : DbContext
{
public UsersContext() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
LazyInitializer.EnsureInitialized(ref _initializer, ref isInitialized, ref initializerLock);
}
public void CheckDatabase()
{
Database.SetInitializer<YourDBContextType>(null);
using (var context = new YourDBContextType())
{
if (!context.Database.Exists())
{
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
// Uses your connection string to build the following table.
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
The end result is not only EF being code first, but also allows for your models for your views to use primitives derived from your complex entities. Now, if you have another, lets say historical, DBContext then I would recommend modifying either the text transformation file or creating a base class for your entities. Both ways allow for an easy generation of code that could insert into your table, then follow up with that entity, clone it into a historical model and save. All that being said, I am a fan of database first approaches with concentration on constraints, triggers, etc. instead of a framework.

EF 4.1 Codefirst: Instantiate complex navigation properties

imagine having a simple POCO for EF 4.1 Codefirst:
public class Product
{
// Native properties
[Key]
public Guid ID { get; set; }
// Navigation properties
public virtual Category Category { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public Product()
{
this.ID = Guid.NewGuid();
// Do I have to instantiate navigation properties in the constructor or not???
this.Category = new Category();
this.Customers = new List<Customer>();
}
}
What I couldn't figure out so far is if I should instantiate complex navigation properties in the POCO's constructor or not?
Seems like all my current code is working if I don't instantiate, but I'm concerned that my code might cause problems in the future.
Are there any rules, best practices or any side effects?
Thanks for your ideas and tips!
You don't need to instantiate Category. Category is single entity which either exists or not - Product is not responsible for its creation. You can need to instantiate Customers to empty list.
The reason why it works now is because your context will wrap entities with dynamic proxy which will handle instantiation of you Customers collection. Because of that other code can access the collection without receiving NullReferenceException. This can change if you create instance of Product in your code without using EF. In such case there will be no dynamic proxy and your collection will be null = you will have to instantiate it yourselves.

NHibernate - Sorting Entities based on Property/Column + how to manage?

I'm writting an ASP.NET MVC e-commerce app using NHibernate and I want the end-user to be able to control the ordering of Product Categories (not just have them appear alphebetically etc.).
Normally, I'd add an OrderIndex/Sort column (of type int) to the Category table, and property to the Category domain class. But the problem is in having to constantly manage this special OrderIndex/Sort column as Categories are sorted, added, and deleted. I'd rather hide it away and make it transparent so callers don't have to set the property directly.
Sure I could write my own code to manage all this, but wanted to know if NHibernate has anything built in that could help me, or if it could hook this property up automatically.
If not then I was thinking of creating an OrderedEntity base class (all domain objects derive from an Entity base), and create an IOrderedRepository base Repository as well. Something like this:
public class Entity
{
public virtual int Id { get; set; }
}
public class OrderedEntity : Entity
{
public virtual int OrderIndex { get; set; }
}
public class Category : OrderedEntity
{
}
public interface IRepository<T> where T : Entity
{
T FromId(int id);
void Save(T entity);
}
public interface IOrderedRepository<T> : IRepository<T> where T : OrderedEntity
{
void MoveUp(int places);
void MoveDown(int places);
}
Does this seem like a good approach? I don't want to reinvent an inferior wheel.
So far I know Hibernate has an annotation #OrderBy where you can specify the ordering when the collection is loaded. But Hibernate won't manage the position that for you when you add or remove element in the collection.
You can however easily do that yourself and provide methods addItem and removeItem on the parent entity, which will keep track of the position (or the methods MoveUp and MoveDown as you suggest).

Resources