using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Xml.Linq;
using System.Configuration;
using System.Data.SqlClient;

namespace BookDemo.DataCache
{
    public partial class CacheDependency : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //当页面被初次Get请求时执行以下代码
            if (!IsPostBack)
            {
                #region 依赖文件

                //依赖项文件路径（一定要是文件绝对路径）
                string filePath = Server.MapPath("~/CacheDependencyFile.xml");
                System.Web.Caching.CacheDependency fileCacheDependency =
                        new System.Web.Caching.CacheDependency(filePath);//创建依赖项参数
                AddCacheDependency("BookDemoFile", fileCacheDependency);

                #endregion


                #region 依赖缓存项

                //依赖文件和缓存项键名（多个）
                string[] cacheKeys = new string[] { "key1", "key2" };
                //依赖缓存项必须事先存在
                if (Cache[cacheKeys[0]] == null)
                    Cache[cacheKeys[0]] = DateTime.Now;
                if (Cache[cacheKeys[1]] == null)
                    Cache[cacheKeys[1]] = DateTime.Now;
                System.Web.Caching.CacheDependency cacheItemCacheDependency =
                        new System.Web.Caching.CacheDependency(new string[] { filePath }, cacheKeys);//创建依赖项参数
                AddCacheDependency("BookDemoCaches", cacheItemCacheDependency);

                #endregion


                #region 依赖数据库

                //依赖项数据库连接字符串
                string connectionString = ConfigurationManager.ConnectionStrings["BookDemoConnectionString"].ToString();
                //依赖数据库表名称（可以是多个）
                string[] tables = new string[] { "CacheDependency" };
                //在程序中启用通知缓存依赖
                System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(connectionString);
                //在程序中启用SQL数据库的缓存依赖项轮询（在数据库中表现为）
                System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString, tables);
                //设置缓存依赖参数
                System.Web.Caching.SqlCacheDependency sqlCacheDependency =
                    new System.Web.Caching.SqlCacheDependency(
                        "BookDemo",//对应Web.config中sqlCacheDependency\databases参数中的name
                        "CacheDependency"//对应数据库表的名称
                        );
                AddCacheDependency("BookDemoSQL", sqlCacheDependency);//添加缓存项

                #endregion


                #region 关联依赖

                //文件依赖
                System.Web.Caching.CacheDependency fileCacheDependency2 =
                                new System.Web.Caching.CacheDependency(filePath);
                //缓存项依赖
                System.Web.Caching.CacheDependency cacheItemCacheDependency2 =
                                new System.Web.Caching.CacheDependency(null, cacheKeys);//创建依赖项参数
                //数据库依赖
                System.Web.Caching.SqlCacheDependency sqlCacheDependency2 =
                    new System.Web.Caching.SqlCacheDependency("BookDemo", "CacheDependency");

                //创建关联依赖AggregateCacheDependency类实例
                System.Web.Caching.AggregateCacheDependency arrCacheDependency = new System.Web.Caching.AggregateCacheDependency();
                //添加关联依赖条件
                arrCacheDependency.Add(
                    fileCacheDependency2, //关联文件依赖
                    cacheItemCacheDependency2,//关联缓存项依赖
                    sqlCacheDependency2//关联数据库依赖
                    );
                AddCacheDependency("BookDemoAggregate", arrCacheDependency);//添加缓存项

                #endregion

                Response.Write("当前时间：" + DateTime.Now.ToString() + "<br />");//当前时间
                Response.Write("BookDemoFile的缓存内容为：" + Cache["BookDemoFile"].ToString() + "<br />");//缓存内时间
                Response.Write("BookDemoCaches的缓存内容为：" + Cache["BookDemoCaches"].ToString() + "<br />");//缓存内时间
                Response.Write("BookDemoSQL的缓存内容为：" + Cache["BookDemoSQL"].ToString() + "<br />");//缓存内时间
                Response.Write("BookDemoAggregate的缓存内容为：" + Cache["BookDemoAggregate"].ToString() + "<br />");//缓存内时间
            }
        }

        /// <summary>
        /// 添加依赖文件的缓存
        /// </summary>
        private void AddCacheDependency(string key, System.Web.Caching.CacheDependency cacheDependency)
        {
            //添加缓存
            if (Cache[key] == null)
            {
                //创建依赖项
                Cache.Insert(key,//缓存键
                    DateTime.Now,//缓存内容
                    cacheDependency//依赖项
                   );
            }
        }

        protected void btnModifyFile_Click(object sender, EventArgs e)
        {
            //如果依赖文件不存在，则创建文件
            if (!File.Exists(Server.MapPath("~/CacheDependencyFile.xml")))
            {
                XDocument xml = new XDocument();//新建XDocument实例
                xml.Add(new XElement("BookDemoCache",//创建根节点
                    new XElement("CacheData", DateTime.Now)//创建子节点，内容为当前时间
                    ));
                xml.Save(Server.MapPath("~/CacheDependencyFile.xml"));//保存为CacheDependencyFile.xml文件
            }

            XDocument dependencyFile = XDocument.Load(Server.MapPath("~/CacheDependencyFile.xml"));//载入CacheDependencyFile.xml文件
            dependencyFile.Root.Element("CacheData").Value = DateTime.Now.ToString();//修改文件
            dependencyFile.Save(Server.MapPath("~/CacheDependencyFile.xml"));//保存文件
            //从新以Get请求打开当前页面，以执行缓存读取内容
            Response.Redirect(Request.Url.PathAndQuery);
        }

        protected void btnModifyCacheItem_Click(object sender, EventArgs e)
        {
            //如果key1缓存项不存在，则新建
            if (Cache["key1"] != null)
                Cache["key1"] = DateTime.Now;

            //如果key2缓存项不存在，则新建
            if (Cache["key2"] != null)
                Cache["key2"] = DateTime.Now;

            //只修改key1缓存项
            Cache["key1"] = DateTime.Now;
            //从新以Get请求打开当前页面，以执行缓存读取内容
            Response.Redirect(Request.Url.PathAndQuery);
        }

        protected void btnModifySQL_Click(object sender, EventArgs e)
        {
            //使用ADO.NET连接数据库
            //获取Web.config的连接字符串，使用ConfigurationManager需要引用System.Data.SqlClient命名空间
            string connectionString = ConfigurationManager.ConnectionStrings["BookDemoConnectionString"].ToString();
            //创建SqlConnection对象实例，用于指定SQL连接的相关参数
            SqlConnection sqlConn = new SqlConnection(connectionString);
            //需要执行的SQL语句
            string sqlText = "insert into CacheDependency (Name) values ('" + DateTime.Now + "')";
            //创建SqlCommand对象实例，用于指定SQL数据库操作的相关参数
            SqlCommand sqlComm = new SqlCommand();
            sqlComm.CommandText = sqlText;//设置SQL语句
            sqlComm.Connection = sqlConn;//设置SQL连接
            sqlConn.Open();//打开SQL数据库连接
            sqlComm.ExecuteNonQuery();//执行数据库操作

            //从新以Get请求打开当前页面，以执行缓存读取内容
            Response.Redirect(Request.Url.PathAndQuery);
        }
    }
}
