Entity Framework 6 Recipes 2nd Edition(12-3)译 -> 数据库连接日志

12-3. 数据库连接日志

问题

你想为每次与数据库的连接和断开记录日志

解决方案

EF为DbContext的连接公开了一个StateChange 事件.我们需要处理这个事件, 为每次与数据库的连接和断开记录日志.

假设我们的模型如Figure 12-3所示. 在 Listing 12-3代码里, 我们创建一些Donation 实例,然后把它们保存到数据库. 这里的代码实现override SaveChanges() 方法为我们的StateChange 事件提供切入点.

 

Figure 12-3. The model with the Donation entity

 

Listing 12-3. Code to Implement Logging of Open and Close of a Database Connection

    class Program

    {

        static void Main(string[] args)

        {

            RunExample();

        }

        static void RunExample()

        {

            using (var context = new EFRecipesEntities())

            {

                context.Donations.Add(new Donation

                {

                    DonorName = "Robert Byrd",

                    Amount = 350M

                });

                context.Donations.Add(new Donation

                {

                    DonorName = "Nancy McVoid",

                    Amount = 250M

                });

                context.Donations.Add(new Donation

                {

                    DonorName = "Kim Kerns",

                    Amount = 750M

                });

                Console.WriteLine("About to SaveChanges()");

                context.SaveChanges();

            }

            using (var context = new EFRecipesEntities())

            {

                var list = context.Donations.Where(o => o.Amount > 300M);

                Console.WriteLine("Donations over $300");

                foreach (var donor in list)

                {

                    Console.WriteLine("{0} gave {1}", donor.DonorName,

                    donor.Amount.ToString("C"));

                }

            }

            Console.WriteLine("Press any key to close...");

            Console.ReadLine();

        }

    }

    public partial class EFRecipesEntities

    {

        public override int SaveChanges()

        {

            this.Database.Connection.StateChange += (s, e) =>

            {

                var conn = (DbConnection)s;

                Console.WriteLine("{0}: Database: {1}, State: {2}, was: {3}",

                DateTime.Now.ToShortTimeString(), conn.Database,

                e.CurrentState, e.OriginalState);

            };

            return base.SaveChanges();

        }

}

上述Listing 12-3代码输出如下:

About to SaveChanges()

09:56 : Database: EFRecipes, State: Open, was: Closed

09:56: Database: EFRecipes, State: Closed, was: Open

Donations over $300

Robert Byrd gave $350.00

Kim Kerns gave $750.00

原理

我们实现override SaveChanges() 方法,为我们的StateChange事件提供切入点,该事件处理程序接收两个参数:事件的发送者(sender)和StateChangeEventArgs.第二个参数提供了访问连接的当前状态和原始状态, 我们为这两个与数据库相关的状态做日志记录.如果你特点注意日志内容的顺序,你会注意到在第二个using块里,与数据库的连接在foreach执行要查询时重新启动,而不是在写查询语句时. 这个演示说明了一个重要的概念:查询只在必要时才进行.在我们的例子中,查询在遍历期间才执行

 

附:创建示例用到的数据库的脚本文件

 

 

posted @ 2016-01-26 13:12  kid1412  阅读(436)  评论(0编辑  收藏  举报