بازنویسی سطح دوم کش برای Entity framework 6
نویسنده: وحید نصیری
تاریخ: ۱۳۹۳/۱۱/۰۶ ۱۶:۵۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
private static ObjectQuery TryGetObjectQuery<T>(IQueryable<T> source)
{
var dbQuery = source as DbQuery<T>;
if (dbQuery != null)
{
const BindingFlags privateFieldFlags =
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
var internalQuery =
source.GetType().GetProperty("InternalQuery", privateFieldFlags)
.GetValue(source);
return
(ObjectQuery)internalQuery.GetType().GetProperty("ObjectQuery", privateFieldFlags)
.GetValue(internalQuery);
}
return null;
} PM> Install-Package EFSecondLevelCache
var products = context.Products.Include(x => x.Tags).FirstOrDefault();
var products = context.Products.Include(x => x.Tags).Cacheable().FirstOrDefault(); // Async methods are supported too.
namespace EFSecondLevelCache.TestDataLayer.DataLayer
{
public class SampleContext : DbContext
{
// public DbSet<Product> Products { get; set; }
public SampleContext()
: base("connectionString1")
{
}
public override int SaveChanges()
{
return SaveAllChanges(invalidateCacheDependencies: true);
}
public int SaveAllChanges(bool invalidateCacheDependencies = true)
{
var changedEntityNames = getChangedEntityNames();
var result = base.SaveChanges();
if (invalidateCacheDependencies)
{
new EFCacheServiceProvider().InvalidateCacheDependencies(changedEntityNames);
}
return result;
}
private string[] getChangedEntityNames()
{
return this.ChangeTracker.Entries()
.Where(x => x.State == EntityState.Added ||
x.State == EntityState.Modified ||
x.State == EntityState.Deleted)
.Select(x => ObjectContext.GetObjectType(x.Entity.GetType()).FullName)
.Distinct()
.ToArray();
}
}
} برای داشتن دو یا چند Context و یا تغییر کانکشن Context میتوان از این Cash استفاده کرد؟
چرا که کلید بر اساس معادل اسکیول عبارت Linq ایجاد میشود
var userInRoles = user.UserInRoles.Union(user.UsersSurrogate.Where(a => a.SurrogateFromDate != null && a.SurrogateToDate != null && a.SurrogateFromDate <= DateTime.Now && a.SurrogateToDate >= DateTime.Now).SelectMany(a => a.UserInRoles));
result = userInRoles.Any(a => a.Role.FormRoles.Any(b => b.IsActive && (b.Select && b.Form.SelectPath != null && b.Form.SelectPath.ToLower().Split(',').Contains(roleName)))); همچنین اتوماتیک بودن Cash به ازای کلیه Queryها هم میتواند یک آپشن در نظر گرفته شود و در مواری که دسترسی به کوئریهای داخلی نیست مفید واقع شود.
مثلا اگر برای اعتبار سنجی کاربر از Identity استفاده شود عملا نمیتوان به کوئریهای داخلی Identity دسترسی پیدا کرد و نیاز است که آن کوئریها Cash شود، چرا که بسیار پرکاربرد میباشند.
public async Task<IList<Bestankaran>> GetBestankaran()
{
EFCachePolicy expirationTime = new EFCachePolicy { AbsoluteExpiration = new DateTime().AddSeconds(60) };
var result =
Task.Run(() =>
_bestankaran.Cacheable(expirationTime).ToListAsync());
return await result;
} public IList<string> GetUserPermissions(int[] roleIds, int userId)
{
var permissionsOfRoles = (from p in _permissions
from r in p.ApplicationRoles
where roleIds.Contains(r.Id)
select p.Name).Cacheable().Future();
var permissionsOfUser = (from p in _permissions
from r in p.AssignedUsers
where userId == r.Id
select p.Name).Cacheable().Future().ToList();
return permissionsOfUser.Union(permissionsOfRoles).ToList();
} The source query must be of type ObjectQuery or DbQuery. Parameter name: source
[ArgumentException: The source query must be of type ObjectQuery or DbQuery. Parameter name: source] EntityFramework.Extensions.FutureExtensions.Future(IQueryable`1 source) +249
var source = users
.Include(d => d.RolesGroup)
.Skip(skipRecords)
.Take(recordsPerPage)
.Cacheable()
.ToList(); public async Task<IdentityResult> RemoveByIdAsync(int userId)
{
var user = FindById(userId);
var identityResult = await DeleteAsync(user);
return identityResult;
} public MyContext()
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.AutoDetectChangesEnabled = false;
} var li = _menus
.Where(m => m.Disable == false && m.LanguageId == culture)
.OrderBy(m => m.Order)
//.Cacheable()
.ToList()
.Where(m => m.ParentId == null)
.ToList(); //function in cache class
public IQueryable<T> FindAll(bool doCache)
{
if (doCache)
return _repository.FindAll(doCache).Cacheable();
else
return _repository.FindAll(doCache);
} // دستور در کلاس سرویس _cache.FindAll(true).Include(s=>s.Tag)
//Function in Repository Class
public IQueryable<T> FindAll(bool doCache, params Expression<Func<T, object>>[] includes)
{
return includes.Aggregate<Expression<Func<T, object>>, IQueryable<T>>(
_dbset, (current, experssion) => current.Include(experssion));
} //function in cache class
public IQueryable<T> FindAll(bool doCache, params Expression<Func<T, object>>[] includes)
{
if (doCache)
{
var result = _repository.FindAll(doCache, includes).Cacheable();
return result;
}
else
return _repository.FindAll(doCache, includes);
} //Call in service class _cache.FindAll(true,s=>s.Tag)
context.DataBase.SqlQuery<x>("Test").Cachable() new EFCacheServiceProvider().ClearAllCachedEntries();
var id = User.GetClaimValue("IdHamayesh").ToInt();
var db = new ApplicationDbContext();
var f= db.Faq.Cacheable().Where(x=>x.IdHamayesh == id && x.IdLanguage == idLanguage).OrderBy(x=>x.Order);
return PartialView(f); var f = db.Faq.Where(x=>x.IdHamayesh == id && x.IdLanguage == idLanguage).OrderBy(x=>x.Order).Cacheable().ToList();
public virtual void Load(IUnitOfWork unitOfWork)
{
//3 get setting for this type name
var settings = unitOfWork.Settings.Where(w => w.Type == _name).Cacheable().ToList(); Trace.WriteLine(string.Format("Changed Entity Names: {0}", changedEntityNames.Aggregate((e1, e2) => string.Format("{0}, {1}", e1, e2)))) var text= context.tbl1.Include(x => x.tbl2).Cacheable().FirstOrDefault();
private readonly IDbSet<Hotel> _hotels;
_hotels = _unitOfWork.Set<Hotel>();
var autoCompletesViewModel = await _hotels.Include(row => row.Profile.City.State.Country).Where(row => row.IsApproved && row.Profile.IsDeleted == false && row.Profile.IsDeactivated == false).Cacheable().ProjectToListAsync<AutoCompleteHotelViewModel>(_mapper.ConfigurationProvider); var autoCompletesViewModelTest = _hotels.Include(row => row.Profile.City.State.Country).Where(row => row.IsApproved && row.Profile.IsDeleted == false && row.Profile.IsDeactivated == false).Cacheable().ProjectToList<AutoCompleteHotelViewModel>(_mapper.ConfigurationProvider);
var autoCompletesViewModel = await _hotels.Include(row => row.Profile.City.State.Country).Where(row => row.IsApproved && row.Profile.IsDeleted == false && row.Profile.IsDeactivated == false).Cacheable().ProjectToListAsync<AutoCompleteHotelViewModel>(_mapper.ConfigurationProvider);
_uow.Set<Post>().Include(x => x.Comments).Cacheable().ToList()
System.NullReferenceException: Object reference not set to an instance of an object. at System.Data.Entity.Internal.Linq.InternalQuery`1.Include(String path) at System.Data.Entity.Infrastructure.DbQuery`1.Include(String path) at System.Data.Entity.QueryableExtensions.Include[T,TProperty](IQueryable`1 source, Expression`1 path)