How to Handle caching with 3-tier design pattern in a website - asp.net

Im developing a asp.net small website and thought about using 3-tier design pattern (Gui, BLL, DAL). My main problem is that i feel bit lost with how should i handle the caching right.
1.First, where should the caching be done? Is it in the GUI website or in the BLL?
2.Second, it feels too messy to me, any chance anyone could provide me a simple example of how caching is done in a good way with all 3 parts of the 3tier?
3.Last, do u find okay to use 3tier for my need?

Personally I really like 3-tier structure and I can only recommend it. Let's see a simple example with some minor caching. We focus on the structure now.
Let's suppose we have the following code-first structure.
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; }
}
Mind that EF will create the primary and foreign keys in the DB by naming conventions (like "Id"). You can use Db-first model as well, not a problem.
Let's have some DTO objects (see MSDN or wiki) like:
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; }
}
Of course categories are not changing often, so we may create some sort of cache for them. The caching in this case is clearly in BLL-level, using Dto objects. Update: This is good only if you have some data that is very unlikely to change but accessed very frequently. Otherwise don't bother with it.
public class MainCache
{
// Make it singleton
// Create some init and a refresh method, watch for thread-safety
public List<CategoryDto> Categories { get; set; }
}
So the controller level can access the cache like this: Update: Now the result of the action itself is cached, see details here. This is a safe solution, the framework does everything.
[HttpGet]
[OutputCache(Duration=10, VaryByParam="none")]
public ActionResult DisplayCategories()
{
// Calling BLL, receiving Dto objects
var model = MainCache.Instance.Categories;
return View(model);
}
Hope, you get it. I think this is a general structure that can be used in various situations. If something is not clear just ask.
Update: Minor code fix, and about caching

Related

Circular Reference with Include in .NET Core

I am using code like below in .NET core
.Include(p => p.Company).ThenInclude(p => p.Country).ToList();
My classes look like below,
public partial class Company
{
public Guid Id { get; set; }
public string Name { get; set; }
public virtual Country Country { get; set; }
}
public partial class Country
{
public Country()
{
Companies = new HashSet<Company>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public string ShortCode { get; set; }
public virtual ICollection<Company> Companies { get; set; }
}
And I want only Company and then Country in side the company to be populated. But I am getting the Company inside the Country and then Country in those Companies and so on populated which is causing the response delayed.
I have already tried difference examples of Include on Google/StackOverFlow.
This isn't actually a problem. EF has what's called "object fix-up". Internally, it uses an object cache. When it builds entity instances for database query results, it adds those to the object cache, allowing it to then pull out those objects later, rather than issuing the same queries again.
Because of this object cache, if it already existing entity instances corresponding to a relationship, it will auto-fill that relationship from the object cache. It's not issuing a series of circular queries forever.

MongoDB basic (Relation between two objects)

I am totally new in mongoDB.
I have two objects :
public class BusinessUnit{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Address{ get; set; } = string.Empty;
}
public class Review
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public decimal Rating { get; set; } = 0;
public BusinessUnit BusinessUnit { get; set; }
}
N.B : Please ignore other properties in given images.
I have a business unit and want to save a review document with that business unit.
I save it successfully. But I am facing a problem.
My problem is after saving a BusinessUnit and review (with that business unit) when I update my BusinessUnit's Name it is unchanged in review document.
I want to know why it's happened.
Am I missing something?
Below is my documents.
Thanks in advance.
MongoDB does not work like Relational databases. So if it is updating in one collection, it wont affect other collection data. No idea where ASP.net internally handles the updation process. Otherwise you need to rethink about your design.

Saving Many to Many relationship data on ASP.NET MVC6 EF7 Create view

I am new to web app development. I am using ASP.NET MVC6 EF7 to create simple app that provides a set of questions to the user, these questions are served on Pages. For reuse, the pages and questions need to have a many-many relationship.
The model (I am developing code-first) is setup as described in the responses to the other posts like this one or this one.
// Data Model
public class Page
{
public int PageID { get; set; } // Key
}
public class Question
{
Public int QID { get; set; } // Key
Public string Text { get; set; } // The question
}
public class PQJoin
{
public int PageID { get; set; }
public virtual Page page { get; set; }
public int QID { get; set; }
public virtual Question question { get; set; }
}
EF Scaffolded CRUD code was used as a starting point.
I would like to link multiple questions to a page when I set it up. In the PagesController:
ViewData["QuestionsID"] = new MultiSelectList(_context.Question, "QID", "Text");
and in the Razor file i create the listbox as follow:
#Html.ListBox("QuestionsID", null, htmlAttributes: new { #class = "form-control" })
So far so good. Problem is I am not sure how to return the newly selected questions from the view and correctly populate the PQJoin table. What is the recommended approach?
You need a link from Page to PQJoin to Question.
Add this to Page and Question class:
public IList<PQJoin> PQJoins {get;set;}

Unable to establish One to Many Relations in MVC 6 Views

As a learning exercise, I was trying to form a simple One to many Relation between Vendors and Shops where each Vendor has multiple shops.
Using two model classes I achieved the following:
This is what scaffolding gives me for Shops
Why am I not getting a drop down here?
Not sharing any code as of now. As most of it is auto generated. Let me know if someone would like me to paste the code for my models.
Another doubt why are my table Columns alphabetically Ordered? If I am not mistaking entity framework 6 used to order it as per the class definition. Is there a way to override it? Cause the view scaffold seems to mirror the DB in terms of ordering objects.
Thanks.
Update:
I added a property Vendorid in the Shops Class. Now I see the Dropdown but no values. Do I need to get down to Fluent API for achieving this?
public class Shops
{
public int Id { get; set; }
public String Name { get; set; }
public int Rank { get; set; }
public String Address { get; set; }
public Boolean Active { get; set; }
public int VendorId { get; set; }
public Vendors Vendor { get; set; }
}
Vendors
public class Vendors
{
public int Id { get; set; }
public String Name { get; set; }
public int Rank { get; set; }
public Boolean Active { get; set; }
public ICollection<Shops> Shops { get; set; }
}
Env: Visual Studio 2015 (Latest ASP.net Patch Applied).
Project Template: Web Application
This depends on what approach on EF you are using. Are you sure they have relationship in their classes? If your using code first, you have to map it manually using fluent API. on OnModelCreating method on DbContext class, use something like this
modelBuilder.Entity().HasMany(v => v.Shop).WithOptional(s => s.Vendor).
If your using Database First, just create relationship on tables diagram(or script) and update the model on your project and EF will create it for you.

Which is the way to add MVC behavior to existing classes?

I have a Windows Form project that I would like to migrate toward a web application using ASP.NET MVC2.
In this project I have some POCO classes as in this example that are part of a class library and that I would like to use with a binary reference
public class Person
{
public int PersonID { get; set; }
public string Name { get; set; }
public DateTime BornDate { get; set; }
...
}
Is there a way to use these classes inside my Web MVC project and adding, for example validation attributes without modifying the original assembly?
thanks for helping
You may take a look at FluentValidation. It integrates nicely with ASP.NET MVC and allows you to unobtrusively add validation rules without modifying your POCO objects.
You can add Meta Information like Validation by using a Partial Class
namespace xxx.Data.yyy
{
[MetadataType(typeof(Posting_Validation))]
public partial class Posting {
}
public class Posting_Validation {
[Required(ErrorMessage = "Need title")]
[StringLength(50, ErrorMessage = "Must be under 50 characters")]
[DisplayName("Title")]
public string Title { get; set; }
[Display(AutoGenerateField = false)]
[HiddenInput(DisplayValue=false)]
public int PostingId { get; set; }
[UIHint("tiny_mce")]
public string HtmlContent { get; set; }
}
}

Resources