返回一个不使用NHibernate对象的列表

本文关键字:NHibernate 对象 列表 一个 返回 | 更新日期: 2023-09-27 18:04:28

假设我有一个接口。

public interface IBlogRepository
{
    IList<Blog> Blogs(int pageNo, int pageSize);
    int TotalPosts();
}

现在我创建了一个类来实现它并使用NHibernate。

using NHibernate;
using NHibernate.Criterion;
using NHibernate.Linq;
using NHibernate.Transform;
using System.Collections.Generic;
using System.Linq;
namespace JustBlog.Core
{
    public class BlogRepository: IBlogRepository
    {
        // NHibernate object
        private readonly ISession _session;
        public BlogRepository(ISession session)
        {
            _session = session;
        }
        public IList<Post> Posts(int pageNo, int pageSize)
        {
            var query = _session.Query<Post>()
                        .Where(p => p.Published)
                        .OrderByDescending(p => p.PostedOn)
                        .Skip(pageNo * pageSize)
                        .Take(pageSize)
                        .Fetch(p => p.Category);
            query.FetchMany(p => p.Tags).ToFuture();
            return query.ToFuture().ToList();
        }
        public int TotalPosts()
        {
            return _session.Query<Post>().Where(p => p.Published).Count();
        }
    }

上面的代码来自web上的某个地方,用于创建博客引擎。但是我根本不懂NHibernate,我用实体框架来做我的工作。

如何重写代码而不使用nhibernate ?

返回一个不使用NHibernate对象的列表

实体模型

假设我们有这样的实体模型:

public class Post
{
    public Post() { Tags = new List<Tag>(); }
    public int Id{ get; set; }
    public string Title{ get; set; }
    public string ShortDescription{ get; set; }
    public string Description{ get; set; }
    public string Meta{ get; set; }
    public string UrlSlug{ get; set; }
    public bool Published{ get; set; }
    public DateTime PostedOn{ get; set; }
    public DateTime? Modified{ get; set; }
    public int CategoryId { get; set; }
    public virtual Category Category{ get; set; }
    public virtual IList<Tag> Tags{ get; set; }
}
public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string UrlSlug { get; set; }
    public string Description { get; set; }
    public virtual IList<Post> Posts { get; set; }
}
public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string UrlSlug { get; set; }
    public string Description { get; set; }
    public virtual IList<Post> Posts { get; set; }
}
<<p> 上下文/strong>

我们的context类非常简单。构造函数接受web.config中连接字符串的名称,并定义三个DbSet s:

public class BlogContext : DbContext
{
    public BlogContext() : base("BlogContextConnectionStringName") { }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

我们的博客存储库的界面很好,很简单,没有太多改变:

public interface IBlogRepository
{
    IEnumerable<Post> Posts(int pageNo, int pageSize);
    int TotalPosts();
}

事情变得有趣的地方是博客存储库本身!

public class BlogRepository : IBlogRepository
{
    // NHibernate object replace with our context
    private readonly BlogContext _blogContext;
    public BlogRepository(BlogContext blogContext)
    {
        _blogContext = blogContext;
    }
    //Function to get a list of blogs
    public IEnumerable<Post> Posts(int pageNo, int pageSize)
    {
        //We start with the blogs db set:
        var query = _blogContext.Posts
            //Filter by Published=true
            .Where(p => p.Published)
            //Order by date they were posted
            .OrderByDescending(p => p.PostedOn)
            //Jump through the list
            .Skip(pageNo * pageSize)
            //Get the required number of blogs
            .Take(pageSize)
            //Make sure the query include all the categories
            .Include(b => b.Category);
        //Just return what we have!
        return query;
    }
    //Much simpler function, should be pretty self explanatory
    public int TotalPosts()
    {
        return _blogContext.Posts.Where(p => p.Published).Count();
    }
}

下一步

好,现在我们已经设置好了所有这些,并且在web中设置了一个漂亮的连接字符串。Config,我们该怎么做?好吧,我们去找一些博客吧!

var context = new BlogContext();
var repository = new BlogRepository(context);
var posts = repository.Posts(0, 10);

然后我们可以对这些博客做一些事情:

foreach(var blog in blogs)
{
    Console.WriteLine("Blog Id {0} was posted on {1} and has {2} categories", blog.Id, blog.PostedOn, blog.Categories.Count());
}
指出

我没有实现FetchMany/ToFuture部分,因为它们在这里不需要

一个简单的方法是使用Linq to Entities从DB映射你的模型。

首先,在您的数据库中创建与您链接的文章中定义的对象完全相同的表,记住添加关系。

然后添加一个ADO实体数据模型,并从选择那些表的数据库填充它,您将以一个XXXEntities结束,它是一个包含所有已经创建的类的ObjectContext。

最后,执行查询将是这样的(假设您的实体命名为BlogEntities):

public IEnumerable<Blog> Posts(int pageNo, int pageSize)
{
    using(BlogEntities con = new BlogEntities())
    {
        var query = con.Post.Include("Category") //<-- If you set "Pluralize fields and properties" when creating your model, it will be "Posts" and "Categories"
                    .Where(p => p.Published)
                    .OrderByDescending(p => p.PostedOn)
                    .Skip(pageNo * pageSize)
                    .Take(pageSize)
                    .ToList();
        return query;
    }
}
public int TotalPosts()
{
    using(BlogEntities con = new BlogEntities())
    {
          return con.Post.Where(p => p.Published).Count();
    }
}