我正在开发一个 asp.net 小型网站,并考虑使用 3 层设计模式(Gui、BLL、DAL)。我的主要问题是我对如何正确处理缓存感到有点迷茫。
1.首先,缓存应该在哪里做?它是在 GUI 网站还是在 BLL 中?2.其次,这对我来说太乱了,任何人都可以提供一个简单的例子来说明如何在 3tier 的所有 3 个部分中以良好的方式完成缓存?3.最后,你觉得可以使用 3tier 来满足我的需要吗?
就个人而言,我真的很喜欢 3 层结构,我只能推荐它。让我们看一个带有一些小缓存的简单示例。我们现在专注于结构。
假设我们有以下代码优先结构。
public class BlogEntry
{
public int Id { get; set; }
public string Title { get; set; }
public string Text { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Blog> Blogs { get; set; }
}
public BlogContext : DbContext
{
public DbSet<Category> Category { get; set; }
public DbSet<BlogEntry> Entry { get; set; }
}
请注意,EF 将通过命名约定(如“Id”)在数据库中创建主键和外键。您也可以使用 Db-first 模型,这不是问题。
让我们有一些 DTO 对象(参见MSDN或wiki),例如:
public class CategoryDto
{
// To use in LINQ .Selector()
public Expression<Func<Category, CategoryDto>> Selector = efCategory => new CategoryDto
{
Id = efCategory.Id,
Name = efCategory.Name,
}
public int Id { get; set; }
public int Name { get; set; }
}
当然类别不会经常变化,所以我们可以为它们创建某种缓存。这种情况下的缓存显然是 BLL 级别的,使用 Dto 对象。更新:只有当您有一些不太可能更改但非常频繁访问的数据时,这才有用。否则别理它。
public class MainCache
{
// Make it singleton
// Create some init and a refresh method, watch for thread-safety
public List<CategoryDto> Categories { get; set; }
}
所以控制器级别可以像这样访问缓存:更新:现在动作本身的结果被缓存了,见这里的细节。这是一个安全的解决方案,框架可以做所有事情。
[HttpGet]
[OutputCache(Duration=10, VaryByParam="none")]
public ActionResult DisplayCategories()
{
// Calling BLL, receiving Dto objects
var model = MainCache.Instance.Categories;
return View(model);
}
希望,你明白了。我认为这是可以在各种情况下使用的通用结构。如果有不清楚的地方问。
更新:次要代码修复,以及关于缓存