Ehsan Ghanbari

Experience, DotNet, Solutions

How to query over Icollection<> of a type with linq

When you are implementing many to many relations in SQL, in the case of using entity framework code fist you must use Icollection<> or Ilist<> of an entity. Imagine that you have this classes, an Author class which has a collection of books

 

    public class Author
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public ICollection<Books> Books { get; set; }
    }

 

And the Books which has a collection of Authors

 

    public class Books
    {
        public int Id { get; set; }
        public string Title { get; set; }

        public ICollection<Author> Authors { get; set; }
    }

 

And this is your context class

 

    public class ContextClass : DbContext
    {
        public DbSet<Books> Books { get; set; }
        public DbSet<Author> Authors { get; set; }
    }

 

If you want you to create a repository class, to get the books by authors Id, You should act like this

 

    public class Repository
    {
        private ContextClass _contextClass = new ContextClass();
        public IEnumerable<Books> FindBookByAuthor(int authorId)
        {
            var query = _contextClass.Books.Where(b => b.Authors.Any(a => a.Id == authorId));
            return query.ToList();
        }
    }

 

In the lambda expression, you have to use any(), because you have a collection of authors in book class. That's all!

 



How to use PagedList In asp.net MVC

PagedList.Mvc is one of many good paging and sorting packages for ASP.NET MVC, in the below simple example I'm gonna implement it for content (posts) of a blog post, install the PagedList.MVC via Nuget and take a look at this code. This is an action which returns blog posts:

 

       public ActionResult List(int? page)
        {
            var posts = _blogService.GetAllBlogPosts();
            var pageNumber = page ?? 1;
            var onePageOfPosts = posts.ToPagedList(pageNumber, 10);
            ViewBag.OnePageOfPosts = onePageOfPosts;
            return View(posts);
        }

 

 I just defined the OnePageOfPosts  ViewBag and onePageOfPosts.  now in the view, you have to add a line of code:

 

@using PagedList
@using PagedList.Mvc;
@model IEnumerable<BlogViewModel>
@{
      ViewBag.Title = "List";
   }
@foreach (var item in Model)
 {
           @Html.ActionLink(item.Title, "Post", "Blog", new { postId = item.PostId, urlSlug = item.UrlSlug }, null)
           @Html.DisplayTextFor(blog => item.Body)
  }

@Html.PagedListPager((IPagedList)ViewBag.OnePageOfPosts, page => Url.Action("List", new { page }) )

 

if you run this piece of code, you should have something like this in the output:

 

<< First < Previous 1 2 3 4 5 … Next > Last >> 

 



Domain driven design VS model driven architecture

Domain Driven design(DDDesign) is not the same Model Driven Architecture(MDA). Although The root of both DDDesign and MDA is the same and it is Model Driven Engineering and also both of them aim to solve the problem of converting a 'pure' problem domain model into a full software system. But there are some differences.

Domain Driven Design concentrates on Modeling and solving the Domain problem by Capturing the model from the Ubiquitous language. it is about modeling a domain of knowledge with a high level of abstraction and its focuses are on domain logic and tries to keep the design as much close to the real world. In DDDesign you create the model with the Ubiquitous language so you should understand the business without any technical issues. In another side, model forms the ubiquitous language of DDDesign which explains the domain in a simple form and it's kinda a backbone of DDDesign.

But Model-driven architecture is an approach to building the model of the system. As I mentioned MDA is a kind of domain engineering too. A model is just some taken classes, methods and ... from the problem domain. MDA provides you to use multiple standards such as UML. 

 

but you know it doesn't stop there, I don't know more than these two paragraphs about differences of DDD and MDA! please let me know more about these two architectures and differences by comments, thanks...



What's the DDD-lite?

Based on Vaughn Vernon 's definition, "DDD-Lite is a means of picking and choosing a subset of the DDD tactical patterns, but without giving full attention to discovering, capturing, and enhancing the Ubiquitous Language." most of the DDD-like approaches are not really DDD! If you don’t have bounded contexts so Ubiquitous language(UL) doesn't mean anything and if you have no UL, you won't have business rules.

In DDD, you should concentrate on a domain model and establish a ubiquitous language and use the patterns of DDD. But most of the cases your application is not complex and big enough to apply the whole DDD approach. but for more and different reasons you are going to use DDD patterns. For example when your application doesn't have any complex and different scenarios to separate them as bounded contexts or SubDomains - and you just embrace technical tools, concepts and patterns of DDD like simple entities, services, repositories, aggregates. In these cases, you can use patterns of DDD within your code and call it "DDD-lite".

I started a project about 10 days ago, it's so interesting that I just read about DDD-lite yesterday; but when I designed the architecture of the project, as I'm really interested in DDD I assigned entities as Aggregate and used the repository and layerSupertype patterns, Repository and Service layers. But I don't have any bounded context, value object, subdomain, UL, Domain Service or context map in this project. I've approximately finished the project, I'm gonna to describe the architecture of the project in a few days after hosting in this tag of my blog with "Statos" title.

As usual, it's my pleasure you to correct my mistakes, thanks



Fluent Nhibernate Sample Project in Asp.net MVC

NHibernate is an ORM designed for Microsoft.Net, it's free and open source and it's a port of Java mapper to Dot Net. And fluent NHibernate is a separate version of NHibernate which lets you write your entities according to your business instead of starting from creating tables, Fluent NHibernate is just a fluent API for mapping classes with NHibernate. what an ORM does, is persisting object In database and then retrieving when it is needed, indeed it translates the object to the database and vice versa.

In Entity Framework, you use DbContext or objectContext(in earlier versions) to make configuration, in this case, Models or properties acts as a UnitOfWork pattern but In NHibernate by Using ISessionFactory Models are keep in a separate in-memory database. I'm going to show a simple NHibernate configuration in this article, Now let's start!

create a new MVC4 project and get the latest version of Fluent NHibernate by Nuget:

NH

Or you can go to the website and get the latest version and reference the Fluent NHibernate, now create a new class named Product : 

 

    public class Product
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual Category Category { get; set; }
    }

 

 and then add the Category Class to your Model folder in your project :

 

    public class Category
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }

 

you should define the properties as virtual because of lazy loading(retrieving an object or so-called data from the database when it's needed is lazy loading) , now create two separate class for mapping this Model classes via Fluent NHibernate :

 

    public sealed class ProductMapping : ClassMap<Product>
    {
        public ProductMapping()
        {
            LazyLoad();
            Table("Product");
            Id(p => p.Id);
            Id(p => p.Id).GeneratedBy.Identity();
            Map(p => p.Name);
            References(p => p.Category);
        }
    }

    public sealed class CategoryMapping : ClassMap<Category>
    {
        public CategoryMapping()
        {
            LazyLoad();
            Table("Category");
            Id(c => c.Id);
            Id(c => c.Id).GeneratedBy.Identity();
            Map(c => c.Name);
        }
     }

 

Now the most important and goal of this article is about configuration class of Fluent NHibernate, create the class with this definition

 

    public class SessionFactory : IHttpModule
    {
        private static readonly ISessionFactory _SessionFactory;
        static SessionFactory()
        {
            _SessionFactory = CreateSessionFactory();
        }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += BeginRequest;
            context.EndRequest += EndRequest;
        }

        public void Dispose()
        {
        }

        public static ISession GetCurrentSession()
        {
            return _SessionFactory.GetCurrentSession();
        }

        private static void BeginRequest(object sender, EventArgs e)
        {
            ISession session = _SessionFactory.OpenSession();
            session.BeginTransaction();
            CurrentSessionContext.Bind(session);
        }

        private static void EndRequest(object sender, EventArgs e)
        {
            ISession session = CurrentSessionContext.Unbind(_SessionFactory);
            if (session == null) return;
            try
            {
                session.Transaction.Commit();
            }
            catch (Exception)
            {
                session.Transaction.Rollback();
            }
            finally
            {
                session.Close();
                session.Dispose();
            }
        }

        private static ISessionFactory CreateSessionFactory()
        {
            return Fluently.Configure()
                           .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c =>    c.FromConnectionStringWithKey("DefaultConnection")))
                           .Mappings(m => m.AutoMappings.Add(CreateMappings()))
                           .CurrentSessionContext<WebSessionContext>()
                           .BuildSessionFactory();
        }

        private static AutoPersistenceModel CreateMappings()
        {
            return AutoMap
                .Assembly(System.Reflection.Assembly.GetCallingAssembly())
                .Where(t => t.Namespace != null && t.Namespace.EndsWith("Models"))
                .Conventions.Setup(c => c.Add(DefaultCascade.SaveUpdate()));
        }
    }

 

Now Open Web.config file and set the connectionString tag :

 

<connectionStrings>
    <add name="DefaultConnection" connectionString="Server=EHSAN\EHSAN;Database=NhMvcDB;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>

 

Notice that NhMvcDB is my database name and DefaultConnection is my connectionString Name and EHSAN\EHSAN is my SQL server instance name!

You should create the Repository class to talk to the database, to make it simple I just create the ProductRepository Class (Not a Generic class for using all entities), to do that add an Interface to your Model :

 

    public interface IProductRepository
    {
        void Add(Product product);
        Product Get(int id);
        void Remove(Product product);
        IEnumerable<Product> GetAll();
        IEnumerable<Product> GetAllProductsByCategoryQuery(int categoryId);
        IEnumerable<Category> GetAllCategoriesQuery();
    }

 

And then  implement the members in ProductRepository class like this

 

    public class ProductRepository : IProductRepository
    {
        private readonly ISession _session;

        public ProductRepository()
        {
            _session = SessionFactory.GetCurrentSession();
        }
        public void Add(Product product)
        {
            SessionFactory.GetCurrentSession().Save(product);
        }

        public Product Get(int id)
        {
            return SessionFactory.GetCurrentSession().Get<Product>(id);
        }

        public void Remove(Product product)
        {
            SessionFactory.GetCurrentSession().Delete(product);
        }

        public IEnumerable<Product> GetAll()
        {
            return _session.Query<Product>();
        }

        public IEnumerable<Product> GetAllProductsByCategoryQuery(int categoryId)
        {
            var products= _session.Query<Product>();
            var productsByCategory = from c in products
                                     where c.Id == categoryId
                                     select c;
            return productsByCategory;
        }

        public IEnumerable<Category> GetAllCategoriesQuery()
        {
            return _session.Query<Category>();
        }
    }

 

Now create the Service interface

 

    public interface IProductService
    {
        void AddProduct(Product product);
        void RemoveProduct(Product productId);
        Product GetProduct(int productId);
        IEnumerable<Product> GetAllProducts();
        IEnumerable<Product> GetAllProductsByCategory(int categoryId);
        IEnumerable<Category> GetAllCategory();
    }

 

And Service implementation :

 

    public class ProductService : IProductService
    {
        private readonly IProductRepository _productRepository;
        public ProductService(IProductRepository productService)
        {
            _productRepository = productService;
        }
        public void AddProduct(Product product)
        {
            _productRepository.Add(product);
        }
        public void RemoveProduct(Product productId)
        {
            _productRepository.Remove(productId);
        }
        public Product GetProduct(int productId)
        {
            var product = new Product { Id = productId };
            return product;
        }
        public IEnumerable<Product> GetAllProducts()
        {
            var products = _productRepository.GetAll();
            return products;
        }
        public IEnumerable<Product> GetAllProductsByCategory(int categoryId)
        {
            var products = _productRepository.GetAllProductsByCategoryQuery(categoryId);
            return products;
        }
        public IEnumerable<Category> GetAllCategory()
        {
            var categories = _productRepository.GetAllCategoriesQuery();
            return categories;
        }
    }
 

 and in Controllers folder create the ProductController with this definition

 

    public class ProductController : Controller
    {
      private readonly IProductService _productService;

        public ProductController(IProductService productService)
        {
            _productService = productService;
        }

        public ActionResult List()
        {
            var products = _productService.GetAllProducts();
            return View(products);
        }

        public ActionResult Add()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Add(Product product)
        {
            if (ModelState.IsValid)
            {
                _productService.AddProduct(product);
            }
            return View();
        }
  }

 

Which list action returns the list of products and by Add action, you can add a product, about the Dependency Resolver, add Ninject by Nuget :

 

Nuget

 

Then add this configuration class to your project

 

    public class NinjectConfig
    {
        private static IKernel _ninjectKernel;
        public class NinjectDependencyResolver : DefaultControllerFactory
        {
            public NinjectDependencyResolver()
            {
                _ninjectKernel = new StandardKernel();
                ConfigurDepndency();
            }
            protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
            {
                return controllerType == null ? null : (IController)_ninjectKernel.Get(controllerType);
            }
        }
        private static void ConfigurDepndency()
        {
            _ninjectKernel.Bind<IProductRepository>().To<ProductRepository>();
            _ninjectKernel.Bind<IProductService>().To<ProductService>();
        }
    }

 

And add this line of code to your global.asax in Application_Start()

 

 ControllerBuilder.Current.SetControllerFactory(new NinjectConfig.NinjectDependencyResolver()); 

 

 end!



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns and I'm spending a lot of my time on architecture subject. Since 2008, I've been as a developer for companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the&nb Read More

Post Tags
Pending Blog Posts
Strategic design
Factory Pattern
time out pattern in ajax
Selectors in Jquery
Peridic pattern
How to query over Icollection<> of a type with linq
How to use PagedList In asp.net MVC
Domain driven design VS model driven architecture
What's the DDD-lite?
Fluent Nhibernate Sample Project in Asp.net MVC