在silverlight中EnitityFramework4.1框架下的以codefirst模式进行后台处理的SQL日志记录方法

来源:互联网 发布:javascript功能 编辑:程序博客网 时间:2024/06/07 07:34
在silverlight底层采用EF4.1框架,采用codefirst模式,花了一天时间才把日志弄上!

1、先学习别人的经验了解最基本的过程,推荐ADO.NET Entity Framework CodeFirst 如何输出日志(EF4.3)

重点是DbContext下的构造函数,需要重载一个带字符串参数的构造函数,同时在调用时使用带连接字符串参数的构造函数

public CommDBContext()            : base("Name=CommContext")        {            this.DbSchema = ParseDbUser.GetDbUserFromConstr(this.Database.Connection.ConnectionString);                    }        
此处不带参数的构造函数也必须要有,另外这里有个针对oracle访问数据表的设计,由于oracle在mapping 时需要指定dbuser,而我需要能够根据配置来实现对应的mapping,所以就需要在构造函数中解析连接字串,将其中的dbuser取出并保存

protected override void OnModelCreating(DbModelBuilder modelBuilder)        {            modelBuilder.Configurations.Add(new T_SYS_USERMap(DbSchema));            modelBuilder.Configurations.Add(new T_SYS_COMPANYMap(DbSchema));        }
这样以后部署的时候不用再担心更改数据库用户了
public CommDBContext(string nameOrConnectionString)            : base(EFTracingUtil.GetConnection(nameOrConnectionString), true)        {            this.DbSchema = ParseDbUser.GetDbUserFromConstr(this.Database.Connection.ConnectionString);            NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();            try            {                var ctx = ((IObjectContextAdapter)this).ObjectContext;                ctx.GetTracingConnection().CommandExecuting += (s, e) =>                {                    log.Info(Environment.NewLine + e.ToTraceString().TrimEnd());                };            }            catch (System.Exception se)            {                log.Error(Environment.NewLine + se.InnerException.Message);            }        }                EFTracingConnection GetTractingConnection()        {            var ctx = ((IObjectContextAdapter)this).ObjectContext;            return ctx.UnwrapConnection<EFTracingConnection>();        }
以上是在dbcontext中所做的工作,在控制台程序中调试是没有问题的,但由于silverlight要实现RIA所以需要使用domianservice,这里很重要刚开始是使用DBdomainservice,结果各种无法解释的错误,无奈之下使用最原始的基类(domainservice),调用方法要注意在domainservice定义个变量,一定要带参数。如下:

CommDBContext Context = new CommDBContext("Name=CommContext");        #region T_SYS_USER 增删改查操作        [Query]        public IEnumerable<T_SYS_USER> GetAllUser()        {            return this.Context.Set<T_SYS_USER>().ToList();        }

2、开始配置日志,由于采用的是Nlog,感觉比log4net简单

<configSections>    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>  </configSections>

添加一个Nlog节点,然后开始配置Nlog节点,如果要记录ip地址别忘了增加nlog扩展,参考点击打开链接

添加IP地址使用${aspnet-request:serverVariable=remote_addr}

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >    <targets>            <target name="file" xsi:type="File" fileName="${basedir}/logs/log_${shortdate}.txt"              layout="[${date:format=yyyy-MM-dd HH\:mm\:ss}][${aspnet-request:serverVariable=remote_addr}] ${message} ${exception}"/>    </targets>    <rules>      <logger name="*" minlevel="error" writeTo="file"></logger>      <logger name="*" minlevel="info" writeTo="file"></logger>    </rules>    <extensions>      <add assembly="NLog.Extended" />    </extensions>  </nlog>
此处别忘了注册EFTracingprovider

<system.data>    <!-- 注册 EF Provider Wrapper -->    <DbProviderFactories>      <add name="EF Tracing Data Provider" invariant="EFTracingProvider" description="Tracing Provider Wrapper" type="EFTracingProvider.EFTracingProviderFactory, EFTracingProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />      <add name="EF Generic Provider Wrapper" invariant="EFProviderWrapper" description="Generic Provider Wrapper" type="EFProviderWrapperToolkit.EFProviderWrapperFactory, EFProviderWrapperToolkit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=def642f226e0e59b" />    </DbProviderFactories>  </system.data>

看看效果,看到那条错误信息就是由于使用的dbdomainservice造成的,花了一晚上也没解决,最后只好改为domainservice了

[2014-01-05 14:53:19][Info] Using the same DbCompiledModel to create contexts against different types of database servers is not supported. Instead, create a separate DbCompiledModel for each type of server being used. [2014-01-05 14:57:37][Info] SELECT "Extent1"."SCOMPANYCODE" AS "SCOMPANYCODE", "Extent1"."SCOMPANYNAME" AS "SCOMPANYNAME",  CAST( "Extent1"."NORDER" AS number(5,0)) AS "C1", "Extent1"."SCOMANYTYPE" AS "SCOMANYTYPE"FROM "TLJKS"."T_SYS_COMPANY" "Extent1" 

附几个下载的地址:EFTacingProvider组件  Nlog

学习silverlight真的好累!2年了就一个人孤独的学习,至今就做个两个项目,架构都是prism+mvvm+EF,数据库一直使用的是oracle这给我开发部署带来痛苦无法言语了,至今在64位下部署都还没有完美的解决方案,各种不兼容很无语了!不过总的来说开始喜欢silverlight了,因为她让我痛并快乐着,下个项目还想部署的到小型机上,困难重重啊!


0 0
原创粉丝点击