I'm just getting my feet wet with Entity Framework, but I'm a bit baffled by some of the behavior of the DBSet Object. When I invoke the Find() method, it seems to be aware of my collection of recently-added (but not yet saved) items, but when I try to query the DBSet, it seems to only include items that have been there all along. Is there an easy way to work around this? I'm including some code that I've done to try to work around this, but when it starts to iterate through the items from my "Added" change set, I get this error:
"Unable to create a constant value of type EntityType. Only primitive types ('such as Int32, String, and Guid') are supported in this context."
internal DbContext Context { get; set; }
protected DbSet<T> DBSet { get; set; }
public virtual IEnumerable<T> Get(
Expression<Func<T, bool>> filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
bool ignoreCachedChanges = false)
{
IQueryable<T> oReturn = DBSet;
// This block is intended to adjust the queryable source to account for changes
if (!ignoreCachedChanges)
{
oReturn = oReturn.Except(Context.ChangeTracker.Entries<T>().Where(x => x.State == System.Data.EntityState.Deleted).Select(x => x.Entity));
oReturn = oReturn.Union(Context.ChangeTracker.Entries<T>().Where(x => x.State == System.Data.EntityState.Added).Select(x => x.Entity));
}
if (filter != null)
oReturn = oReturn.Where(filter);
if (orderBy != null)
return orderBy(oReturn).ToList();
else
return oReturn.ToList();
}
// NOTE: Get By ID uses Find which considers the queued-but-not-yet-applied changes
public virtual T GetByID(object id)
{
return DBSet.Find(id);
}
(In case context helps, I'm doing this because I want to set up a unit test where I populate my (local) context with items that cater to my particular testing environment...I'd just as soon not have to apply those changes since they're really only applicable for that particular test, but I can if need be...In doing that, I was surprised to see that the repository was not including changed items in its queried results -- unless I was doing the FindByID -- so I'm also hoping I can either resolve that apparent inconsistency, or get a better undersanding of why that's not doable...or not a good idea? :) )
The exception says it: You cannot send a list of entity types (of your generic type T) to the server to execute Except
and Union
in SQL with these collections of "constant" objects. Basically you must apply Except
and Union
in memory with LINQ to Objects, which means: after the filtered result from the server has been materialized (so, somewhere after .ToList()
). You have to apply the filter a second time to the list of objects in the context which are in Added
state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With