你的分享就是我们的动力 ---﹥

新做的NHibernate项目,大家来拍拍砖,同时还要请多多提些问题

时间:2013-05-21 14:06来源:www.chengxuyuans.com 点击:

简单说明:

这个项目的结构,大家来拍拍砖,同时还要请多多提些问题。

这个结构是根据之前的项目结构,以及院子里不是朋友们的提供的方案、代码等,整合起来的。不敢妄称为啥框架,只是希望对开发的项目能起到一些帮助作用。

第一次写blog,可能有点乱,大家见谅了。

使用结构资源

NHibernate.net
FluentNHibernate
Autofac
MVC
Jquery

项目结构

总体结构

说明下为啥这样做: 我工作的单位都是变化比较快的公司(命苦呀),很多事情都是比较杂,之前的项目就是模块太多了,维护起来很麻烦,我就想可不可以按照功能模块来划分, 吧一个模块深入,又不影响其他人的工作。。。 所以倒腾了这样的一个结果。(受到SpaceBuilder影响).



文章咨询模块


稍微了解过NHibernate.net应该能开出来大概的结构意思吧? 还是上几段代码吧。

using System;using System.Linq;using System.Text;using Job.FluenCore.Common;using Iesi.Collections.Generic;namespace Job.FluenCore.Article.Model{    public class News : IEntity    {        /// <summary>        /// 文章编号        /// </summary>        public virtual int Id { get; set; }        /// <summary>        /// 新闻类型何种类型        /// 文章、单页        /// News.TypeId =NewsClass.TypeId        /// </summary>        public virtual NewsClassType TypeId { get; set; }        /// <summary>        /// News.ClassId =NewsClass.ClassId        /// </summary>        public virtual int ClassId { get; set; }        /// <summary>        /// 访问次数        /// </summary>        public virtual int Visits { get; set; }        /// <summary>        /// 添加时间        /// </summary>        public virtual DateTime AddTime { get; set; }        /// <summary>        /// 编辑时间        /// </summary>        public virtual DateTime EditTime { get; set; }        /// <summary>        /// 文章状态        /// </summary>        public virtual NewAuditType ContentStatus { get; set; }        /// <summary>        /// 主题 详细页        /// </summary>        public virtual string Title { get; set; }        /// <summary>        /// 主题颜色        /// </summary>        public virtual string TitleColor { get; set; }        /// <summary>        /// 复标题 用于首页等。        /// </summary>        public virtual string TitleSub { get; set; }        /// <summary>        /// 内容        /// </summary>        public virtual string Content { get; set; }        /// <summary>        /// 作者        /// </summary>        public virtual string Author { get; set; }        /// <summary>        /// 简介        /// </summary>        public virtual string Introduction { get; set; }        /// <summary>        /// seo        /// </summary>        public virtual string PageTitle { get; set; }        /// <summary>        /// seo        /// </summary>        public virtual string PageKeywords { get; set; }        /// <summary>        /// seo        /// </summary>        public virtual string PageDescription { get; set; }        /// <summary>        /// 置顶        /// </summary>        public virtual byte IsTop { get; set; }        /// <summary>        /// 推荐        /// </summary>        public virtual byte IsRecommend { get; set; }        /// <summary>        /// 回复        /// </summary>        public virtual byte IsNoComment { get; set; }        /// <summary>        /// 文章星级 默认 0        /// </summary>        public virtual short Star { get; set; }        /// <summary>        /// 文章排序 默认 0        /// </summary>        public virtual int ContentOrder { get; set; }        /// <summary>        /// 文章Url        /// </summary>        public virtual string ContentUrl { get; set; }        /// <summary>        /// 缩略图 编号        /// </summary>        public virtual int IndexImage { get; set; }                /*        /// <summary>        /// 文章分类\        /// 数据库字段=ClassID        /// </summary>        public virtual NewsClass Class { get; set; }        /// <summary>        /// 文章评论        /// </summary>        public virtual ISet<NewsComments> Comments { get; set; }         ///// <summary>        ///// 图片 下载文件        ///// </summary>        public virtual ISet<NewsFile> Files { get; set; }        */    }}
模型
using System;//using System.Collections.Generic;using System.Linq;using Iesi.Collections.Generic;using FluentNHibernate.Mapping;using Job.FluenCore.Article.Model;namespace Job.FluenCore.Article.Mapping{    public class NewsMap : ClassMap<News>    {        public NewsMap()        {            Table("[t_News]");            Id(p => p.Id).GeneratedBy.Identity();            Map(p => p.ClassId).Not.Nullable().Default("0");            Map(p => p.Title).Not.Nullable().Length(255);            Map(p => p.TitleColor).Nullable().Length(10);            Map(p => p.TitleSub).Nullable().Length(255);            Map(p => p.Content).Nullable().CustomSqlType("text");            Map(p => p.Author).Nullable().Length(50);            Map(p => p.Introduction).Nullable().Length(1000);            Map(p => p.PageTitle).Nullable().Length(100);            Map(p => p.PageKeywords).Nullable().Length(100);            Map(p => p.PageDescription).Nullable().Length(255);            Map(p => p.IsTop).Not.Nullable().Default("0");            Map(p => p.IsRecommend).Not.Nullable().Default("0");            Map(p => p.IsNoComment).Not.Nullable().Default("0");            Map(p => p.Star).Not.Nullable().Default("0");            Map(p => p.ContentOrder).Not.Nullable().Default("0");            Map(p => p.ContentUrl).Nullable().Length(255);            Map(p => p.IndexImage).Not.Nullable().Default("0");            Map(p => p.Visits).Not.Nullable().Default("0");            Map(p => p.AddTime).Not.Nullable().Default("getdate()");            Map(p => p.EditTime).Not.Nullable().Default("getdate()");            Map(p => p.ContentStatus).CustomType<NewAuditType>();            /*            References<NewsClass>(p => p.Class)                .LazyLoad()                .Column("ClassID")                .Cascade.All();                        HasMany<NewsComments>(p => p.Comments)                .AsSet().LazyLoad()                .Inverse() //    Inverse="false"(默认):父实体负责维护关联关系     Inverse="true":子实体负责维护关联关系                .KeyColumn("NewsID")                .Cascade.All();            HasMany<NewsFile>(p => p.Files)                .AsSet().LazyLoad()                .Inverse() //    Inverse="false"(默认):父实体负责维护关联关系     Inverse="true":子实体负责维护关联关系                .KeyColumn("NewsID")                .Cascade.All();            */        }    }}
映射
using System;using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;using Webdiyer.WebControls.Mvc;using Job.FluenCore.Common;using Job.FluenCore.DateFactory;using Job.FluenCore.Article.Mapping;using Job.FluenCore.Article.Model;namespace Job.FluenCore.Article.Repository{    #region Interface    public interface INewsRepository : IRepositoryBase<News>    {        void UpdateHitClick(int Id);    }    #endregion    public class NewsRepository : RepositoryBase<News>, INewsRepository    {        public NewsRepository(IDatabaseFactory databaseFactory)            : base(databaseFactory)        {        }        public void UpdateHitClick(int Id)        {            var s = "update [t_News] set Visits=Visits+1 whre Id=:f1";            base.CreateSQLQuery(s)                .SetInt32("f1", Id)                .ExecuteUpdate();            //base.Commit();        }    }}
数据工厂
using System;using System.Collections.Generic;using System.Linq;using System.Text;//using System.Data.Entity.Validation;using Webdiyer.WebControls.Mvc;using Job.FluenCore.Common;using Job.FluenCore.DateFactory;using Job.FluenCore.Article.Model;using Job.FluenCore.Article.Repository;namespace Job.FluenCore.Article.Service{    public interface INewsService : IServiceBase<INewsRepository>    {        void UpdateHitClick(int Id, string Ip);    }    public class NewsService : ServiceBase<INewsRepository>, INewsService    {        public NewsService(IUnitOfWork _unitwork, INewsRepository _repository)            : base(_unitwork, _repository)        {         }        public void UpdateHitClick(int Id, string Ip)        {            base.Repository().UpdateHitClick(Id);            /*            var s = "update [t_News] set Visits=Visits+1,ip=:f2 whre Id=:f1";                        base.Repository().CreateSQLQuery(s)                .SetInt32("f1", Id)                .SetString("f2", Ip)                .ExecuteUpdate();            base.Repository().Commit();            */        }    }}
数据服务
using System;using System.Collections.Specialized;using System.Web;using System.Web.Mvc;using System.Web.Routing;using Autofac;using Job.FluenCore.Article.Mapping;using Job.FluenCore.Article.Model;using Job.FluenCore.Article.Repository;using Job.FluenCore.Article.Service;namespace Job.FluenCore.Article.Modules{    public class NewsModule : Module    {        protected override void Load(ContainerBuilder builder)        {            if (builder == null)            {                throw new ArgumentNullException("Job.FluenCore.Article.Modules ContainerBuilder");            }            builder.RegisterType<NewsService>().As<INewsService>().InstancePerLifetimeScope();            builder.RegisterType<NewsRepository>().As<INewsRepository>().InstancePerLifetimeScope();            builder.RegisterType<NewsClassService>().As<INewsClassService>().InstancePerLifetimeScope();            builder.RegisterType<NewsClassRepository>().As<INewsClassRepository>().InstancePerLifetimeScope();            base.Load(builder);        }        public System.Reflection.Assembly GetAssembly()        {            return System.Reflection.Assembly.GetExecutingAssembly();        }    }}
注册服务
namespace Job.FluenCore.DateFactory{    public interface IRepositoryBase<T> where T : class    {        /// <summary>        /// 提交事务        /// </summary>        void Commit();        /// <summary>        /// 添加        /// </summary>        /// <param name="entity"></param>        /// <param name="IsNowSave"></param>        /// <returns></returns>        T Add(T entity, bool IsNowSave = true);        /// <summary>        /// 更新        /// </summary>        /// <param name="entity"></param>        /// <param name="IsNowSave"></param>        void Update(T entity, bool IsNowSave = true);        void SaveOrUpdate(T entity, bool IsNowSave = true);        void Delete(T entity);        void Delete(int Id, bool Load = false);        void Delete(Expression<Func<T, bool>> where);        T GetById(int Id);        T GetById(string Id);        /// <summary>        /// 根据条件获得模型 Linq语句        /// </summary>        /// <param name="where"></param>        /// <returns></returns>        T Get(Expression<Func<T, bool>> where);        /// <summary>        /// 支持 selector where查询        /// var list= GetMany(o => o.Id > 0).Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        T Get(Expression<Func<T, bool>> where, Expression<Func<T, T>> selector);        /// <summary>        /// 支持 select where orderby查询        /// var list= GetMany().Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        IQueryable<T> GetMany();        /// <summary>        /// 支持 select orderby查询        /// var list= GetMany(o => o.Id > 0).Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        IQueryable<T> GetMany(Expression<Func<T, bool>> where);        /// <summary>        /// 支持 where查询        /// var list= GetList(o => o.Id > 0).Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        PagedList<T> GetList(Expression<Func<T, bool>> where, int pagesize, int pageindex);        /// <summary>        /// 支持 select where查询        /// var list= GetList(o => o.Id > 0).Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        PagedList<T> GetList(Expression<Func<T, bool>> where, Expression<Func<T, T>> select, int pagesize, int pageindex);        /// <summary>        /// 支持 select where查询        /// var list= GetList(o => o.Id > 0).Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        PagedList<T> GetList(Expression<Func<T, bool>> where, Expression<Func<T, T>> select, Func<T, string> orderName, string sortOrder, int pagesize, int pageindex);        /// <summary>        /// 支持 select where查询        /// var list= GetForModel[T](o => o.Id > 0).Select(o => o).OrderByDescending(o=>o.AddTime).ToPagedList(pageindex, pagesize);        /// </summary>        IQueryable<TModel> GetForModel<TModel>();        /// <summary>        /// 支持NHibernate语句,查询、更新、删除        /// eg .CreateCriteria().add(Expression.like("name", "Fritz%")).add( Expression.between("weight", minWeight, maxWeight))        /// </summary>        ICriteria CreateCriteria();        /// <summary>        /// 支持NHibernate语句,查询、更新、删除        /// eg .CreateCriteria().add(Expression.like("name", "Fritz%")).add( Expression.between("weight", minWeight, maxWeight))        /// </summary>        ICriteria CreateCriteria(string entityName);                /// <summary>        /// 支持 hql,参数,查询、更新、删除\ 注意不是SQL        /// hibernate 中createQuery与createSQLQuery两者区别是:前者用的hql语句进行查询,后者可以用sql语句查询|        /// eg .CreateQuery("from Customer c where c.Name.Firstname=:fn and c.Name.Lastname=:ln").SetString("fn", firstname).SetString("ln", lastname)        /// </summary>        IQuery CreateQuery(string queryString);        /// <summary>        /// 支持 SQL、参数,查询、更新、删除  更新语句请加 ExecuteUpdate|        /// 注意:需使用正确的 数据表结构字段         /// eg CreateSQLQuery("select ID from News where id=:f1 and IsTop>5").SetString("f1", firstname) \         /// eg CreateSQLQuery("{Call sp_Login(?,?) }").SetString(0, "admin").SetString(1, "admin");        /// </summary>        ISQLQuery CreateSQLQuery(string queryString);                     /// <summary>        /// 分页查询(sql分页方式) 统计        /// 注意:需使用正确的 数据表结构字段         /// </summary>        System.Collections.Generic.IList<TModel> GetListForPaging<TModel>(string tableName, int pageNumber, int pageSize, string orderName, string sortOrder, string CommandText, out int Count);        /// <summary>        /// 分页查询(sql分页方式) 不统计        /// 注意:需使用正确的 数据表结构字段         /// </summary>        System.Collections.Generic.IList<TModel> GetListForPaging<TModel>(string tableName, int pageNumber, int pageSize, string orderName, string sortOrder, string CommandText);        /// <summary>        /// 原生SQL关联查询        /// 注意:需使用正确的 数据表结构字段         /// </summary>        System.Collections.Generic.IList<TModel> GetListForPaging<TModel>(string strQuery);        /// <summary>        /// 原生SQL关联查询        /// 注意:需使用正确的 数据表结构字段         /// </summary>        System.Data.DataSet GetDataSet(string strQuery);        /// <summary>        /// 计算总个数(分页)        /// </summary>        int GetCount(string tableName, string commandText);    }
数据工厂基础接口
using System;using System.Text;using System.Web;using System.Web.Mvc;using System.Web.Mvc.Html;using System.Linq;using System.Linq.Expressions;using System.Collections.Generic;using System.Data;using System.Data.Entity;using System.ComponentModel;using Job.FluenCore.Ceche;using Webdiyer.WebControls.Mvc;using DotNet.Common;using Job.FluenCore.Common;using Job.FluenCore.Common.MVCFormwork;using Job.FluenCore.Article;using Job.FluenCore.Article.Model;using Job.FluenCore.Article.Repository;using Job.FluenCore.Article.Service;namespace Job.Web.Controller{    public class NewsController : BaseWebController    {        protected readonly INewsService _NewsService;        protected readonly INewsClassService _NewClassService;                public NewsController(INewsService NewsService, INewsClassService NewClassService)        {            this._NewsService = NewsService;            this._NewClassService = NewClassService;        }        #region web        [HttpGet]        public virtual ActionResult Index(int? page, int intPid = 0, int intStatus = 1)        {            //int _page = page ?? GetPageIndex();            //var stus = (NewsClassStatusType)intStatus;            //var where = PredicateExtensions.True<News>();            //if (intStatus == 0 || intStatus == 1) { where = where.And(p => p.Status == stus); }            //if (intPid > 0) { where = where.And(p => p.ParentId == intPid); }            //var list = _NewsService            //    .Repository()            //    .GetList(where, GetPageSize(), _page);            //PageData();            return View();        }        [HttpGet]        public virtual ActionResult Detail(int id, int intStatus = 1)        {            //var data = _NewsService.Repository().GetById(id);            //data = data ?? new News();            //PageData();            return View();        }        #endregion        #region admin        /* true 显示错误; false 继续 */        [LoginAllowView]        [Description("[详细信息]检查是否存在(add,Update必备)")]        public ActionResult CheckExist()        {            var action = QueryString.Request["action"];            var ID = QueryString.Request["ID"].GetNum(0);            var val = QueryString.Request[action];            var b = false;            if (!val.IsNullOrWhiteSpace())            {                switch (action)                {                    case "ContentUrl":                        b = _NewsService.Repository().GetMany(p => p.Id != ID && p.ContentUrl == val).Any();                        break;                }            }            b = !b;            return Content(b.ToString().ToLower());        }        [Description("[Index主页]新闻管理")]        [ViewPage]        [DefaultPage]        public ActionResult AdminIndex(int Type = 0)        {            var CurrentTypeID = Type;            var titel = typeof(NewsClassType).GetEnumDictionaryA().GetValue(CurrentTypeID);            titel = titel ?? "文章";            ViewBag.Title = titel + "管理";            ViewBag.CurrentID = CurrentTypeID;            return View();        }        [ViewPage]        [Description("[详细信息]新闻详细信息(add,Update,Detail必备)")]        public ActionResult AdminDetail()        {            ViewBag.IsView = (QueryString.Request["IsView"] == "1") ? 1 : 0;            ViewBag.CurrentID = QueryString.Request["ID"].GetNum(0);            return View();        }        [Description("[Get Json]获取新闻Json")]        [LigerUIExceptionResult]        public ActionResult AdminGet(int? id)        {            var _id = id ?? 0;            var data = _NewsService.Repository().Get(o => o.Id == _id);            data = data ?? new News();            return this.JsonFormat(data, true, "获取[新闻]");        }        [Description("[系统]添加动作")]        [LigerUIExceptionResult]        public ActionResult AdminAdd()        {            News model = new News();            this.TryUpdateModel(model);            model.Id = 0;            model.AddTime = model.AddTime == null ? DateTime.UtcNow : model.AddTime;            model.EditTime = model.AddTime == null ? DateTime.UtcNow : model.EditTime;            return AdminSave(model);        }        [Description("[系统]修改动作")]        [LigerUIExceptionResult]        public ActionResult AdminUpdate()        {            News model = new News();            this.TryUpdateModel(model);            model.AddTime = model.AddTime == null ? DateTime.UtcNow : model.AddTime;            model.EditTime = model.AddTime == null ? DateTime.UtcNow : model.EditTime;            return AdminSave(model);        }        [Description("[Delete]页面删除请求")]        [LigerUIExceptionResult]        public ActionResult AdminDelete(int Id)        {            var status = true;            _NewsService.Repository().Delete(Id);            return this.JsonFormat(null, status, "删除[新闻]");        }                [Description("[gridRequest请求]获取新闻")]        [LoginAllowView]        public ActionResult AdminGetGrid()        {            var gridRequest = new LigerUIGridRequest(HttpContext);            var where = gridRequest.Where;            var parms = FilterHelper.GetFilterTanslateQuery(ref where);            int Count = _NewsService.Repository().GetMany()                .Where(where, parms)                .Count();            var data = _NewsService.Repository().GetMany()                .Where(where, parms)                .OrderBy(gridRequest.SortName + " " + gridRequest.SortOrder)                .Skip((gridRequest.PageNumber - 1) * gridRequest.PageSize)                .Take(gridRequest.PageSize)                .Select(o => new                {                    Id = o.Id,                    Title = o.Title,                    TitleColor = o.TitleColor,                    EditTime = o.EditTime,                    ContentUrl = o.ContentUrl,                    ContentStatus = o.ContentStatus,                    IndexImage = o.IndexImage,                    IsNoComment = o.IsNoComment,                    IsRecommend = o.IsRecommend,                    IsTop = o.IsTop,                    Visits = o.Visits,                    Star = o.Star,                    AddTime = o.AddTime,                    //TypeId = o.TypeId,                    ClassId = o.ClassId                })                .ToList();            var grid = new LigerUIGrid();            grid.Rows = data;            grid.Total = Count;            return this.JsonFormat(grid);        }        #endregion        #region heper        [NonAction]        public ActionResult AdminSave(News model)        {            var status = SaveNewsClass(model, model.Id > 1);            return this.JsonFormat(null, status, "保存[新闻分类]");        }        public bool SaveNewsClass(News model, bool IsEdit = true)        {            if (model == null) { return false; }            model.AddTime = DateTimeHelper.DateTimeYeas(model.AddTime);            model.EditTime = DateTimeHelper.DateTimeYeas(model.EditTime);            model.ClassId = model.ClassId < 0 ? QueryString.Request["ClassId"].GetNum(0) : model.ClassId;            if (IsEdit)            {                _NewsService.Repository().Update(model);            }            else            {                _NewsService.Repository().Add(model);            }            return true;        }        #endregion    }}
新闻资讯操作实例


同时我们对Linq的扩展也可以流畅的对数据操作。


 

不过这里也有一些问题需要改进;1 目前的动态自定义查询问题, 2 跨表问题(目前可用试图、存储过程处理);
让使用者自己可以控制查询字段、条件、显示结果字段、排序等;
如:
_NewsService.Repository().GetMany()
                .Where("id=1 and t<10")  ===》
                .OrderBy("id desc")
                .Take(10)
                .Skip(10)
                .Select("New(Id,Title)");



未完。。。。 
先下班了。。。 晚上再写。


转载注明地址:http://www.chengxuyuans.com/Javaframework/61288.html