// ****************************************************** 
// 文件名称(File Name)：   Products.cs
// 项目名称(Project Name)：猛犸商贸演示系统
// 功能描述(Description)： 实现 产品 业务接口（此模块的功能描述与大概流程说明）
// 数据表(Tables)：        Products（所用到的数据表，视图，存储过程的说明，如关系比较复杂，则应说明哪些是可擦写的，哪些表为只读的）
// 作者(Author)：          zhaoshunlu@163.com
// 日期(Create Date)：     2014-10-21 21:48:52
// 参考文档(Reference)(可选)： （该档所对应的分析文档，设计文檔）
// 引用(Using) (可选)﹕        （开发的系统中引用其它系统的Dll、对象时，要列出其对应的出处，是否与系统有关﹙不清楚的可以不写﹚，以方便制作安装档）
// 修改记录(Revision History)：（若档案的所有者改变，则需要有修改人员的名字、修改日期及修改理由）
//****************************************************** 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Northwind.Model;
using Northwind.IDAL;
using Northwind.DALFactory;

namespace Northwind.BLL {
    /// <summary>
    /// 产品（Products）  
    /// </summary>
    /// <remarks> 
    /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
    /// <para>修改人、日期及内容:</para>
    /// </remarks>
    public class ProductsBLL {
        //获取程序集名称(不含后缀名),Web的Bin目录下的程序集
        static string path = System.Configuration.ConfigurationManager.AppSettings["NorthwindDAL"];

        /// <summary>
        /// 声明接口
        /// </summary>
        /// <value>
        /// Northwind.IDAL.IProducts
        /// </value>
        Northwind.IDAL.IProducts dal;
        
        /// <summary>
        /// 产品
        /// </summary>
        public ProductsBLL() {
            dal = AbstractFactory.Create<Northwind.IDAL.IProducts>(path, path + ".ProductsDAL");//由工厂模式生成
        }

        /// <summary>
        /// 获取最后的最内部的错误异常信息
        /// </summary>
        /// <returns>返回最后一条错误/异常信息</returns>
        /// <value>
        /// string
        /// </value>
        public string GetLastError() {
            return dal.GetLastError();
        }

        #region 常规常用CRUD操作 公用成员方法组GetOne()、GetList()、GetPage()、GetPages()、Insert()、Update()、Delete()、Save()

        #region 获取单个对象(一条记录)
        /// <summary>       
        /// 通过主键获取一条记录       
        /// </summary>
        /// <param name="ProductID">要查询的键值 如: 100</param>        
        /// <param name="state">自定义设置查询标志：如all 对象所有信息包括子对象（子表）信息，single 仅仅当前表信息</param>  
        /// <returns>返回一个Products对象或者null</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>  
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     Northwind.Model.Products model = bll.GetOne(10); 
        ///     ]]>  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// Northwind.Model.Products
        /// </value>
        public Northwind.Model.Products GetOne(int ProductID, string state = "all") {
            return dal.GetOne(ProductID, state);
        }

        //YourAdminLoginExists
        #endregion

        #region 获取普通列表(无翻页)
        // 1、ALinq Dynamic (Linq to SQL Dynamic Query)
        /// <summary>
        /// 使用LINQ动态查询所有或部分记录         
        /// </summary>      
        /// <param name="conditionLinq">Linq Dynamic查询条件</param>    
        /// <returns>返回一组Products集合对象</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     //注意Linq to SQL Dynamic 动态查询,是查询对象属性名称而不是字段名称，有大小写区别。
        ///     //模糊查询EnCusCode.Contains(\"1002\")相对于SQL:EnCusCode like '%1002%',EnCusCode.Substring(0,4)==\"1002\"相对于SQL:EnCusCode like '1002%'
        ///     IList<Northwind.Model.Products> Productss = bll.GetList(" EnCusCode==\"" + enCusCode + "\" AND SaleDate>=DateTime(2013,9,10)");
        ///     ]]>  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// IList<Northwind.Model.Products>
        /// </value>
        public IList<Northwind.Model.Products> GetList(string conditionLinq) {
            return dal.GetList(conditionLinq);
        }
        /// <summary>
        /// 使用LINQ动态查询所有或部分记录      
        /// </summary>
        /// <param name="top">返回数量</param>
        /// <param name="selector">要查询的匿名对象属性集合字符串</param>
        /// <param name="conditionLinq">Linq Dynamic查询条件</param>
        /// <param name="order">Linq Dynamic排序属性及方式</param>
        /// <returns>返回一组Products集合对象</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     //注意Linq to SQL Dynamic 动态查询,是查询对象属性名称而不是字段名称，有大小写区别。
        ///     //模糊查询EnCusCode.Contains(\"1002\")相对于SQL:EnCusCode like '%1002%',EnCusCode.Substring(0,4)==\"1002\"相对于SQL:EnCusCode like '1002%'
        ///     IList<Northwind.Model.Products> Productss = bll.GetListWithLinq(-1, "new(ID,EnCusCode,OrderStatue,UserSeat,SaleDate,Mobile)", " EnCusCode==\"" + enCusCode + "\" AND SaleDate>=DateTime(2013,9,10)", "ID Desc");
        ///     ]]>  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// IList<Northwind.Model.Products>
        /// </value>
        public IList<Northwind.Model.Products> GetList(int top, string selector, string conditionLinq, string order) {
            return dal.GetList(top, selector, conditionLinq, order);
        }

        //2、使用Lambda表达式
        /// <summary>    
        /// 使用Lambda表达式查询获取所有或部分记录       
        /// </summary>
        /// <param name="whereLambda">查询条件 Lambda表达式</param>
        /// <returns>返回一组Products集合对象</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     Func<Northwind.Model.Products, bool> whereLambda = w => w.ProductName.Contains("张");//"张"为查询关键字词        
        ///     IList<Northwind.Model.Products> Productss = bll.GetList(whereLambda);     
        ///     ]]>  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// IList<Northwind.Model.Products>
        /// </value>
        public IList<Northwind.Model.Products> GetList(Expression<Func<Northwind.Model.Products, bool>> whereLambda) {
            return dal.GetList(whereLambda);
        }

        /// <summary>    
        /// 使用Lambda表达式查询获指定行数的部分记录
        /// </summary>
        /// <typeparam name="S">排序键的数据类型</typeparam>
        /// <param name="top">指定返回记录条数</param>
        /// <param name="whereLambda">查询条件Lambda表达式</param>
        /// <param name="orderLambda">排序Lambda表达式</param>
        /// <param name="isAsc">是否按升序排序,默认false</param>
        /// <returns>返回一组Products集合对象</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     Func<Northwind.Model.Products, bool> whereLambda = w => w.ProductName.Contains("张");//"张"为查询关键字词 
        ///     Func<Northwind.Model.Products, int> whereLambda = w => w.ProductID;  //按主键排序    
        ///     IList<Northwind.Model.Products> Productss = bll.GetList(10,whereLambda,orderByLambda,false);     
        ///     ]]>  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// IList<Northwind.Model.Products>
        /// </value>
        public IList<Northwind.Model.Products> GetList<S>(int top, Expression<Func<Northwind.Model.Products, bool>> whereLambda, Expression<Func<Northwind.Model.Products, S>> orderLambda, bool isAsc = false) {
            return dal.GetList<S>(top, whereLambda, orderLambda, isAsc);
        }

        //3、使用原始SQL命令表达式查询
        //注意：
        //以下2个查询记录的方法调用时参数直接使用到了数据表字段名称
        //如果数据表字段名称修改了，那么原先调用的程序将会得不到期望的结果甚至导致程序异常。     

        /// <summary>      
        /// 通过查询获取所有或部分记录   
        ///  <para>参数<paramref name="conditionSQL"/> 必须是正确的SQL查询条件表达式.表格字段名称必须正确</para>       
        /// </summary>
        /// <param name="conditionSQL">查询条件 如: Name like '%张%'；为空或者null就返回所有数据</param>
        /// <param name="orderSQL">排序方式，默认null，为空或者null则按默认排序</param>
        /// <param name="top">查询记录条数，默认0，小于1则不限制返回行数</param>
        /// <returns>返回一组Products集合对象</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>       
        ///     <![CDATA[
        ///         Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///         string conditionSQL = "ProductName like '%张%'";         
        ///         IList<Northwind.Model.Products> Productss = bll.GetList(conditionSQL);
        ///     ]]>          
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// IList<Northwind.Model.Products>
        /// </value>
        public IList<Northwind.Model.Products> GetListUseSQL(string conditionSQL, string orderSQL = null, int top = 0) {
            return dal.GetListUseSQL(conditionSQL, orderSQL, top);
        }

        /// <summary>
        /// 通过原始SQL命令查询获取所有或部分记录   
        /// 必须是正确的SQL查询条件表达式.
        /// </summary>        
        /// <param name="top">指定返回记录条数,小于1则不限制返回行数</param>
        /// <param name="selector">投影字段,null或者""或者"*"返回所有字段</param>
        /// <param name="conditionSQL">查询条件如：SaleItem like '%张%'</param>  
        /// <param name="order">排序如：ID Desc</param>          
        /// <returns>DataTable</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>       
        ///     <![CDATA[
        ///         Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();      
        ///         DataTable table = bll.GetTableUseSQL(10,"ID,Title,Date","Title like '%海南%'","ID Desc");
        ///     ]]>          
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// DataTable
        /// </value>
        public DataTable GetTableUseSQL(int top, string selector, string conditionSQL, string orderSQL) {
            return dal.GetTableUseSQL( top,  selector,  conditionSQL,  orderSQL);
        }
        #endregion

        #region 获取翻页列表
        /// <summary>       
        /// 通过Linq 动态查询获取所有或部分记录,
        /// <para>按指定的字段或者属性名称进行排序，只能对一个字段进行排序,</para>
        /// <para>并将结果进行分页</para>       
        /// <para>参数<paramref name="propertyName"/> 是对象的属性名称,不是表格字段名称.</para>
        /// </summary>        
        /// <param name="pageSize">每页数据行数</param>
        /// <param name="pageIndex">当前页面</param>        
        /// <param name="conditionLinq">Linq查询条件表达式</param>
        /// <param name="isAsc">是否按升序排序</param>
        /// <param name="propertyName">要排序的属性名称(不是字段名称)</param>
        /// <param name="total">输出总记录条数</param>
        /// <returns>返回一组Products集合对象</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     string conditionLinq =" ProductName==\"" + enCusCode + "\" AND YourDate>=DateTime(2013,9,10) AND YourContent.Contains(\"" + enCusCode + "\")" //key为查询关键字词 如"张"        
        ///     string propertyName = "name";                                           //按字段 name 进行排序
        ///     bool isAsc = false;                                                     //默认按降序排序
        ///     int total = 0;                                                          //缓存方法输出的数据总行数        
        ///     IList<Northwind.Model.Products> Productss = bll.GetPage(pageSize, pageIndex, conditionLinq, isAsc, propertyName, out total);
        ///     //遍历所有记录
        ///     //foreach (Northwind.Model.Products model in Productss)
        ///     //{
        ///     //     model.
        ///     //}     
        ///     ]]>
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// IList<Northwind.Model.Products>
        /// </value>
        public IList<Northwind.Model.Products> GetPage(int pageSize, int pageIndex, string conditionLinq, bool isAsc, string propertyName, out int total) {
            return dal.GetPage(pageSize, pageIndex, conditionLinq, isAsc, propertyName, out total);
        }

        //注意：
        //以下查询翻页记录的方法调用时参数直接使用到了数据表字段名称
        //如果数据表字段名称修改了，那么原先调用的程序将会得不到期望的结果甚至导致程序异常。
        /// <summary>      
        /// <para>通过原始的SQL命令查询获取所有或部分记录,可以从表格或者视图获取记录,</para>
        /// <para>按指定的字段或者属性名称进行排序，只能对一个字段进行排序,</para>
        /// <para>并将结果进行分页</para>      
        /// <para>参数<paramref name="conditionSQL"/> 必须是正确的SQL查询条件表达式.表格字段名称必须正确</para>
        /// <para>参数<paramref name="sortField"/> 必须是表格字段名称.</para>
        /// </summary>  
        /// <param name="pageSize">每页数据行数</param>
        /// <param name="pageIndex">当前页面</param>        
        /// <param name="conditionSQL">SQL查询条件表达式</param>
        /// <param name="isAsc">是否按升序排序</param>
        /// <param name="sortField">要排序的属性名称(字段名称)</param>
        /// <param name="total">总记录条数,如果pageIndex=0 或者total=0，就查询总记录数，否则就不查询总记录数</param>
        /// <param name="bStatistics">是否进行服务端统计,默认false不统计</param>
        /// <returns>返回一个哈希表</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>  
        ///     <![CDATA[
        ///    Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     string conditionSQL = "ProductName like '%"+key+"%'";   //key为查询关键字词 如"张"
        ///     string sortField = "name";                                      //按字段 name 进行排序
        ///     bool isAsc = false;                                                     //默认按降序排序
        ///     int total = 0;                                                          //缓存方法输出的数据总行数        
        ///     Hashtable result = bll.GetPages(pageSize, pageIndex, conditionSQL, isAsc, sortField, total);
        ///     //result["data"]  是 IList<Hashtable>每一项一行数据;
        ///     //result["total"] 是 总记录数;
        ///     ]]>   
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// Hashtable
        /// </value>
        public Hashtable GetPages(int pageSize, int pageIndex, string conditions, bool isAsc, string fieldName, int total, bool bStatistics = false) {
            return dal.GetPages(pageSize, pageIndex, conditions, isAsc, fieldName, total, bStatistics);
        }
        #endregion

        #region 增删改操作
        /// <summary>       
        /// 插入一条新记录  
        /// </summary>
        /// <param name="model">要添加的实体对象</param>
        /// <returns></returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///      Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///      bll.Insert(model);  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// bool
        /// </value>
        public bool Insert(Northwind.Model.Products model) {
            return dal.Insert(model);
        }

        /// <summary>      
        /// 修改原有的一条记录  
        /// </summary>
        /// <param name="model">要修改的实体对象</param>
        /// <returns></returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     bll.Update(model);     
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// bool
        /// </value>
        public bool Update(Northwind.Model.Products model) {
            return dal.Update(model);
        }

        /// <summary>      
        /// 更新表单提交的数据 
        /// <para>必须指定要修改的属性名称集合</para>
        /// </summary>
        /// <param name="model">要修改的实体对象</param>
        /// <param name="SetKes">要修改的属性名称集合</param>
        /// <param name="FilterKeys">特别指定需要排除的属性键集合,默认为null</param>
        /// <returns>更新成功返回true,失败返回false</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     <![CDATA[
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     bll.Update(model,new string[]{"Name","Sex"});     
        ///     ]]> 
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>bool</value>
        public bool UpdateForm(Northwind.Model.Products model, string[] SetKes = null) {
            return dal.UpdateForm(model, SetKes);
        }


        /// <summary>      
        /// 通过主键删除一条或多条记录（通过判断参数中的逗号分隔符来决定是否删除多条记录）
        /// </summary>
        /// <param name="ProductID">要删除的键值，如24，或者是以逗号分隔的主键集合，如：2,34,50,36</param>
        /// <param name="CompanyCode">公司编码</param>
        /// <param name="OpMaker">操作人名称</param>
        /// <returns></returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///         Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///         bll.Delete(23);  
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// bool
        /// </value>
        public bool Delete(string Keys, string CompanyCode = null, string OpMaker = null) {
            return dal.Delete(Keys, CompanyCode,OpMaker);
        }

        /// <summary>      
        /// 通过主键删除一条或多条记录（通过判断参数中的逗号分隔符来决定是否删除多条记录）,并输出要删除的文件列表
        /// </summary>
        /// <param name="Keys">要删除的主键集合（以逗号,分隔）</param>
        /// <param name="files">输出要删除的文件列表</param>
        /// <param name="OpMaker">操作人名称</param>
        /// <returns>删除成功返回true,失败返回false</returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///     IList<string> files = new List<string>();
        ///     Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///     bll.Delete("2,34,50,36",out files);   
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// bool
        /// </value>
        public bool Delete(string Keys, out IList<string> files,string OpMaker = null) {
            return dal.Delete(Keys, out files, OpMaker);
        }
        #endregion

        #region 保存与批量保存操作
        /// <summary>    
        /// 保存数据单个对象（一条记录）   
        /// </summary>
        /// <param name="model">要保存的对象实例</param>
        /// <returns></returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///         Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///         bll.Save(model);     
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// bool
        /// </value>
        public bool Save(Northwind.Model.Products model) {
            if (model == null) {
                return false;
            }
            return dal.Save(model);
        }

        /// <summary>        
        /// 批量保存多条记录(可以混合删除、新增、修改操作) 
        /// </summary>
        /// <param name="models">要保存的对象实例集合</param>    
        /// <returns></returns>
        /// <example> 这是一个例子显示如何调用此方法
        ///     <code>   
        ///         Northwind.BLL.ProductsBLL bll = new Northwind.BLL.ProductsBLL();
        ///         bll.Save(models);      
        ///     </code>
        /// </example>
        /// <remarks> 
        /// 创建人及日期：zhaoshunlu@163.com 2014-10-21 21:48:52
        /// <para>修改人、日期及内容:</para>
        /// </remarks>
        /// <value>
        /// bool
        /// </value>
        public bool Save(IList<Northwind.Model.Products> models) {
            if (models == null || models.Count == 0) {
                return false;
            }
            return dal.Save(models);
        }
        #endregion

        #endregion

        //以下是 你的自定义业务逻辑
        #region 你的自定义业务逻辑



        #endregion
    }
}
