Skip to content

Instantly share code, notes, and snippets.

@frookypoon
Last active December 17, 2015 21:48
Show Gist options
  • Save frookypoon/5676956 to your computer and use it in GitHub Desktop.
Save frookypoon/5676956 to your computer and use it in GitHub Desktop.
C# - EntityFramework - DbSet<T>.Find(...) and the inability to use it with Includes (Yes, some of us don't want to use lazy loading for fracksake). Here's one way to make it generic
/*
* Tested on EF 5
*/
using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace frooky.com.redacted.DataAccessLayer.Domain {
public abstract class DomainAbstract<EntityType> where EntityType : class {
private MyEntities _context;
protected MyEntities Context {
get { return _context; }
}
// must be overriden in inherited classes for primary key lookup (As DbSet<T>.Find
// does not work with include!! Oh yes, it assumes all your entities have an Int as
// a primary key - you can make the Pk type generic here if you have different types
// of primary keys
protected abstract Expression<Func<EntityType, bool>> primaryKeyPredicate(int pkId);
public DomainAbstract(MyEntities Context) {
_context = Context;
}
// Find by int Id with includes
public virtual EntityType read(int id, params string[] includes) {
var query = ((DbQuery<EntityType>)_context.Set<EntityType>());
query = includes.Aggregate(query, (q, s) => q.Include(s));
// return query.FirstOrDefault(primaryKeyPredicate(id));
return query.SingleOrDefault(primaryKeyPredicate(id));
}
public virtual IEnumerable<EntityType> read(params string[] includes) {
var query = ((DbQuery<EntityType>)_context.Set<EntityType>());
query = includes.Aggregate(query, (q, s) => q.Include(s));
return query.ToList();
}
}
}
var context = new MyEntities();
context.Configuration.LazyLoadingEnabled = false;
var functions = new StockManagementMethods(context);
StockItem si = functions.read(456, "StockLocation", "BaseColours", "Recipes.BaseColour")
namespace frooky.com.redacted.DataAccessLayer
{
using System;
using System.Collections.Generic;
// Generated POCO
public partial class StockItem
{
public StockItem()
{
this.BaseColours = new HashSet<BaseColour>();
this.Recipes = new HashSet<Recipe>();
this.StockMovements = new HashSet<StockMovement>();
}
public int StockItemId { get; set; }
public Nullable<int> QuantityOnHandInGrams { get; set; }
public Nullable<int> StockLocationId { get; set; }
public virtual ICollection<BaseColour> BaseColours { get; set; }
public virtual ICollection<Recipe> Recipes { get; set; }
public virtual StockLocation StockLocation { get; set; }
public virtual ICollection<StockMovement> StockMovements { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace frooky.com.redacted.DataAccessLayer.Domain {
public class StockManagementMethods : DomainAbstract<StockItem> {
// predicate for specified primary key
protected override System.Linq.Expressions.Expression<Func<StockItem, bool>> primaryKeyPredicate(int pkId) {
return (si) => si.StockItemId == pkId;
}
public StockManagementMethods(MyEntities Context) : base(Context) {
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment