问题:

1.GMail是通过SSL来接收邮件的

解决方法:

步骤1.log4net的StmpAppender默认情况下是不支持SSL的,你需要小小的修改下log4net的源代码.

找到SmtpAppender.cs文件后,打开文件,修改源代码以支持EnableSSL属性.

修改方式为:

1.增加EnableSSL属性。

2.修改SendMail方法,设置局部变量smtpClient的EnableSsl属性为添加的EnableSSL属性.

修改后的类如下

#region Copyright & License
//
// Copyright 2001-2005 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

#define NET_2_0

// .NET Compact Framework 1.0 has no support for System.Web.Mail
// SSCLI 1.0 has no support for System.Web.Mail
#if !NETCF && !SSCLI

using System;
using System.IO;

#if NET_2_0
using System.Net.Mail;
#else
using System.Web.Mail;
#endif

using log4net.Layout;
using log4net.Core;
using log4net.Util;

namespace log4net.Appender
{
	/// <summary>
	/// Send an e-mail when a specific logging event occurs, typically on errors 
	/// or fatal errors.
	/// </summary>
	/// <remarks>
	/// <para>
	/// The number of logging events delivered in this e-mail depend on
	/// the value of <see cref="BufferingAppenderSkeleton.BufferSize"/> option. The
	/// <see cref="SmtpAppender"/> keeps only the last
	/// <see cref="BufferingAppenderSkeleton.BufferSize"/> logging events in its 
	/// cyclic buffer. This keeps memory requirements at a reasonable level while 
	/// still delivering useful application context.
	/// </para>
	/// <note type="caution">
	/// Authentication and setting the server Port are only available on the MS .NET 1.1 runtime.
	/// For these features to be enabled you need to ensure that you are using a version of
	/// the log4net assembly that is built against the MS .NET 1.1 framework and that you are
	/// running the your application on the MS .NET 1.1 runtime. On all other platforms only sending
	/// unauthenticated messages to a server listening on port 25 (the default) is supported.
	/// </note>
	/// <para>
	/// Authentication is supported by setting the <see cref="Authentication"/> property to
	/// either <see cref="SmtpAuthentication.Basic"/> or <see cref="SmtpAuthentication.Ntlm"/>.
	/// If using <see cref="SmtpAuthentication.Basic"/> authentication then the <see cref="Username"/>
	/// and <see cref="Password"/> properties must also be set.
	/// </para>
	/// <para>
	/// To set the SMTP server port use the <see cref="Port"/> property. The default port is 25.
	/// </para>
	/// </remarks>
	/// <author>Nicko Cadell</author>
	/// <author>Gert Driesen</author>
	public class SmtpAppender : BufferingAppenderSkeleton
	{
		#region Public Instance Constructors

		/// <summary>
		/// Default constructor
		/// </summary>
		/// <remarks>
		/// <para>
		/// Default constructor
		/// </para>
		/// </remarks>
		public SmtpAppender()
		{	
		}

		#endregion // Public Instance Constructors

		#region Public Instance Properties

		/// <summary>
		/// Gets or sets a semicolon-delimited list of recipient e-mail addresses.
		/// </summary>
		/// <value>
		/// A semicolon-delimited list of e-mail addresses.
		/// </value>
		/// <remarks>
		/// <para>
		/// A semicolon-delimited list of recipient e-mail addresses.
		/// </para>
		/// </remarks>
		public string To 
		{
			get { return m_to; }
			set { m_to = value; }
		}

		/// <summary>
		/// Gets or sets the e-mail address of the sender.
		/// </summary>
		/// <value>
		/// The e-mail address of the sender.
		/// </value>
		/// <remarks>
		/// <para>
		/// The e-mail address of the sender.
		/// </para>
		/// </remarks>
		public string From 
		{
			get { return m_from; }
			set { m_from = value; }
		}

		/// <summary>
		/// Gets or sets the subject line of the e-mail message.
		/// </summary>
		/// <value>
		/// The subject line of the e-mail message.
		/// </value>
		/// <remarks>
		/// <para>
		/// The subject line of the e-mail message.
		/// </para>
		/// </remarks>
		public string Subject 
		{
			get { return m_subject; }
			set { m_subject = value; }
		}
  
		/// <summary>
		/// Gets or sets the name of the SMTP relay mail server to use to send 
		/// the e-mail messages.
		/// </summary>
		/// <value>
		/// The name of the e-mail relay server. If SmtpServer is not set, the 
		/// name of the local SMTP server is used.
		/// </value>
		/// <remarks>
		/// <para>
		/// The name of the e-mail relay server. If SmtpServer is not set, the 
		/// name of the local SMTP server is used.
		/// </para>
		/// </remarks>
		public string SmtpHost
		{
			get { return m_smtpHost; }
			set { m_smtpHost = value; }
		}

		/// <summary>
		/// Obsolete
		/// </summary>
		/// <remarks>
		/// Use the BufferingAppenderSkeleton Fix methods instead 
		/// </remarks>
		/// <remarks>
		/// <para>
		/// Obsolete property.
		/// </para>
		/// </remarks>
		[Obsolete("Use the BufferingAppenderSkeleton Fix methods")]
		public bool LocationInfo
		{
			get { return false; }
			set { ; }
		}

		/// <summary>
		/// The mode to use to authentication with the SMTP server
		/// </summary>
		/// <remarks>
		/// <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
		/// <para>
		/// Valid Authentication mode values are: <see cref="SmtpAuthentication.None"/>, 
		/// <see cref="SmtpAuthentication.Basic"/>, and <see cref="SmtpAuthentication.Ntlm"/>. 
		/// The default value is <see cref="SmtpAuthentication.None"/>. When using 
		/// <see cref="SmtpAuthentication.Basic"/> you must specify the <see cref="Username"/> 
		/// and <see cref="Password"/> to use to authenticate.
		/// When using <see cref="SmtpAuthentication.Ntlm"/> the Windows credentials for the current
		/// thread, if impersonating, or the process will be used to authenticate. 
		/// </para>
		/// </remarks>
		public SmtpAuthentication Authentication
		{
			get { return m_authentication; }
			set { m_authentication = value; }
		}

		/// <summary>
		/// The username to use to authenticate with the SMTP server
		/// </summary>
		/// <remarks>
		/// <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
		/// <para>
		/// A <see cref="Username"/> and <see cref="Password"/> must be specified when 
		/// <see cref="Authentication"/> is set to <see cref="SmtpAuthentication.Basic"/>, 
		/// otherwise the username will be ignored. 
		/// </para>
		/// </remarks>
		public string Username
		{
			get { return m_username; }
			set { m_username = value; }
		}

		/// <summary>
		/// The password to use to authenticate with the SMTP server
		/// </summary>
		/// <remarks>
		/// <note type="caution">Authentication is only available on the MS .NET 1.1 runtime.</note>
		/// <para>
		/// A <see cref="Username"/> and <see cref="Password"/> must be specified when 
		/// <see cref="Authentication"/> is set to <see cref="SmtpAuthentication.Basic"/>, 
		/// otherwise the password will be ignored. 
		/// </para>
		/// </remarks>
		public string Password
		{
			get { return m_password; }
			set { m_password = value; }
		}

		/// <summary>
		/// The port on which the SMTP server is listening
		/// </summary>
		/// <remarks>
		/// <note type="caution">Server Port is only available on the MS .NET 1.1 runtime.</note>
		/// <para>
		/// The port on which the SMTP server is listening. The default
		/// port is <c>25</c>. The Port can only be changed when running on
		/// the MS .NET 1.1 runtime.
		/// </para>
		/// </remarks>
		public int Port
		{
			get { return m_port; }
			set { m_port = value; }
		}

		/// <summary>
		/// Gets or sets the priority of the e-mail message
		/// </summary>
		/// <value>
		/// One of the <see cref="MailPriority"/> values.
		/// </value>
		/// <remarks>
		/// <para>
		/// Sets the priority of the e-mails generated by this
		/// appender. The default priority is <see cref="MailPriority.Normal"/>.
		/// </para>
		/// <para>
		/// If you are using this appender to report errors then
		/// you may want to set the priority to <see cref="MailPriority.High"/>.
		/// </para>
		/// </remarks>
		public MailPriority Priority
		{
			get { return m_mailPriority; }
			set { m_mailPriority = value; }
		}

        /// <summary>
        /// Gets or sets the enable of ssl for sending e-mail
        /// </summary>
        public bool EnableSSL
        {
            get { return m_enableSSL; }
            set { m_enableSSL = value; }
        }


		#endregion // Public Instance Properties

		#region Override implementation of BufferingAppenderSkeleton

		/// <summary>
		/// Sends the contents of the cyclic buffer as an e-mail message.
		/// </summary>
		/// <param name="events">The logging events to send.</param>
		override protected void SendBuffer(LoggingEvent[] events) 
		{
			// Note: this code already owns the monitor for this
			// appender. This frees us from needing to synchronize again.
			try 
			{	  
				StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);

				string t = Layout.Header;
				if (t != null)
				{
					writer.Write(t);
				}

				for(int i = 0; i < events.Length; i++) 
				{
					// Render the event and append the text to the buffer
					RenderLoggingEvent(writer, events[i]);
				}

				t = Layout.Footer;
				if (t != null)
				{
					writer.Write(t);
				}

				SendEmail(writer.ToString());
			} 
			catch(Exception e) 
			{
				ErrorHandler.Error("Error occurred while sending e-mail notification.", e);
			}
		}

		#endregion // Override implementation of BufferingAppenderSkeleton

		#region Override implementation of AppenderSkeleton

		/// <summary>
		/// This appender requires a <see cref="Layout"/> to be set.
		/// </summary>
		/// <value><c>true</c></value>
		/// <remarks>
		/// <para>
		/// This appender requires a <see cref="Layout"/> to be set.
		/// </para>
		/// </remarks>
		override protected bool RequiresLayout
		{
			get { return true; }
		}

		#endregion // Override implementation of AppenderSkeleton

		#region Protected Methods

		/// <summary>
		/// Send the email message
		/// </summary>
		/// <param name="messageBody">the body text to include in the mail</param>
		virtual protected void SendEmail(string messageBody)
		{
#if NET_2_0
			// .NET 2.0 has a new API for SMTP email System.Net.Mail
			// This API supports credentials and multiple hosts correctly.
			// The old API is deprecated.

			// Create and configure the smtp client
			SmtpClient smtpClient = new SmtpClient();
			if (m_smtpHost != null && m_smtpHost.Length > 0)
			{
				smtpClient.Host = m_smtpHost;
			}
			smtpClient.Port = m_port;
			smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.EnableSsl = m_enableSSL;

			if (m_authentication == SmtpAuthentication.Basic)
			{
				// Perform basic authentication
				smtpClient.Credentials = new System.Net.NetworkCredential(m_username, m_password);
			}
			else if (m_authentication == SmtpAuthentication.Ntlm)
			{
				// Perform integrated authentication (NTLM)
				smtpClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
			}
            

			MailMessage mailMessage = new MailMessage();
			mailMessage.Body = messageBody;
			mailMessage.From = new MailAddress(m_from);
			mailMessage.To.Add(m_to);
			mailMessage.Subject = m_subject;
			mailMessage.Priority = m_mailPriority;

			// TODO: Consider using SendAsync to send the message without blocking. This would be a change in
			// behaviour compared to .NET 1.x. We would need a SendCompletedCallback to log errors.
			smtpClient.Send(mailMessage);
#else
				// .NET 1.x uses the System.Web.Mail API for sending Mail

				MailMessage mailMessage = new MailMessage();
				mailMessage.Body = messageBody;
				mailMessage.From = m_from;
				mailMessage.To = m_to;
				mailMessage.Subject = m_subject;
				mailMessage.Priority = m_mailPriority;

#if NET_1_1
				// The Fields property on the MailMessage allows the CDO properties to be set directly.
				// This property is only available on .NET Framework 1.1 and the implementation must understand
				// the CDO properties. For details of the fields available in CDO see:
				//
				// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_configuration_coclass.asp
				// 

				try
				{
					if (m_authentication == SmtpAuthentication.Basic)
					{
						// Perform basic authentication
						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1);
						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", m_username);
						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", m_password);
					}
					else if (m_authentication == SmtpAuthentication.Ntlm)
					{
						// Perform integrated authentication (NTLM)
						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 2);
					}

					// Set the port if not the default value
					if (m_port != 25) 
					{
						mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", m_port);
					}
				}
				catch(MissingMethodException missingMethodException)
				{
					// If we were compiled against .NET 1.1 but are running against .NET 1.0 then
					// we will get a MissingMethodException when accessing the MailMessage.Fields property.

					ErrorHandler.Error("SmtpAppender: Authentication and server Port are only supported when running on the MS .NET 1.1 framework", missingMethodException);
				}
#else
				if (m_authentication != SmtpAuthentication.None)
				{
					ErrorHandler.Error("SmtpAppender: Authentication is only supported on the MS .NET 1.1 or MS .NET 2.0 builds of log4net");
				}

				if (m_port != 25)
				{
					ErrorHandler.Error("SmtpAppender: Server Port is only supported on the MS .NET 1.1 or MS .NET 2.0 builds of log4net");
				}
#endif // if NET_1_1

				if (m_smtpHost != null && m_smtpHost.Length > 0)
				{
					SmtpMail.SmtpServer = m_smtpHost;
				}

				SmtpMail.Send(mailMessage);
#endif // if NET_2_0
		}

		#endregion // Protected Methods

		#region Private Instance Fields

		private string m_to;
		private string m_from;
		private string m_subject;
		private string m_smtpHost;
        private bool m_enableSSL;

		// authentication fields
		private SmtpAuthentication m_authentication = SmtpAuthentication.None;
		private string m_username;
		private string m_password;

		// server port, default port 25
		private int m_port = 25;

		private MailPriority m_mailPriority = MailPriority.Normal;

		#endregion // Private Instance Fields

		#region SmtpAuthentication Enum

		/// <summary>
		/// Values for the <see cref="SmtpAppender.Authentication"/> property.
		/// </summary>
		/// <remarks>
		/// <para>
		/// SMTP authentication modes.
		/// </para>
		/// </remarks>
		public enum SmtpAuthentication
		{
			/// <summary>
			/// No authentication
			/// </summary>
			None,

			/// <summary>
			/// Basic authentication.
			/// </summary>
			/// <remarks>
			/// Requires a username and password to be supplied
			/// </remarks>
			Basic,

			/// <summary>
			/// Integrated authentication
			/// </summary>
			/// <remarks>
			/// Uses the Windows credentials from the current thread or process to authenticate.
			/// </remarks>
			Ntlm
		}

		#endregion // SmtpAuthentication Enum
	}
}

#endif // !NETCF && !SSCLI

步骤2:在你的项目中引用新的编译后的log4net.dll。在配置文件中如下设置



<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="to1@gmail.com,to2@gmail.com" />
<from value="from@gmail.com" />
<subject value="your_subject" />
<smtpHost value="smtp.gmail.com" />
<authentication value="Basic" />
<username value="your_gmail_account_name@gmail.com" />
<password value="your_gmail_account_password" />
<enablessl value="true" />
<port value="25" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator,log4net">
<threshold value="ERROR" />
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newlineLevel :%level%newlineThread :%thread%newlineLogger :%logger%newlineDate :%date{yyyy-MM-dd HH:mm:ss}%newlineMessage :%message%newlineException :%newline%exception%newline" />
</layout>
</appender>
posted @ 2011-03-31 19:43 东风31 阅读(172) 评论(2) 编辑

1.查看数据库连接的sql语句

use master;
select * from sysprocesses where dbid in (select dbid from sysdatabases where name ='数据库名');

2.允许将显式值插入表的标识列中。

SET IDENTITY_INSERT

语法

SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }

3.重置identity列的值

  查看表tablename的自增列的当前值

dbcc checkident('tablename',NORESEED)

  设置表tablename的自增列的当前值为value

dbcc checkident('tablename',RESEED,value)


注意,自增列的下一个值是value+1,无论你的自增列的reseed设置的是多少。如果我们想要初始化
自增列的值,可以设置为 dbcc checkident('tablename',RESEED,0)

4.判断数据库中是否存在指定的表

Object_ID(N'Fact.KeywordBidPlanDemo','T') is not null


5.设置日期的格式

set dateformat {format_string}

format_string中d表示day,m表示month,y表示year.
可选的值有:mdy、dmy、ymd、ydm、myd 和 dym

SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。 
IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。
@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值
SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。

例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。

假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。

@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。

SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。

而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。 

附:使用@IDENTITY基本知识 

1. IDENTITY 列不能由用户直接更新,它是由系统自动维护的。 

2.该列数据类型必须为数值型:int, smallint, tinyint, decimal or numeric with scale 0。 

3.该列不能为 null。 

4.不能在该列上设置缺省值。 

5.递增量只能为整形(比如:1,2,-3)。不能为小数,也不能为0。 

6.基值(种子值 seed)可以由用户设置,缺省值为1。 

理解 @@IDENTITY 

@@IDENTITY 返回最后一个插入 IDENTITY 的值,这些操作包括:INSERT, SELECT INTO,或者 bulk copy。如果在给没有 IDENTITY 列的其他表插入记录,系统将其置为 null。如果有多行记录插入到 IDENTITY 表中,@@IDENTITY 表示最后一个产生的值。如果触发了某个触发器,并且这个触发器执行向另一个带有 IDENTITY 列的表的插入操作,@@IDENTITY 将返回这个由触发器产生的值。如果这个触发器插入的表中不包含 IDENTITY 列,那么 @@IDENTITY 将为 null。如果插入操作失败,@@IDENTITY 值依然会增加,所以 IDENTITY 不保证数据的连续性。 

@@IDENTITY 是当前连接的全局变量,只对当前连接有效。也就是说,如果断开连接再重新连接后,@@IDENTITY 为 null。以 ADO 来说,@@IDENTITY 在 Connection 对象打开和关闭期间是有意义的,即在 Connection 对象的存在范围内有效。在 MTS 组件中,从打开连接到显式的关闭连接(Connection.Close)或者到调用了 SetAbort,SetComplete之前,在这期间,@@IDENTITY 有意义。

posted @ 2010-12-27 09:31 东风31 阅读(25) 评论(0) 编辑

实体的持久化状态

1.读状态(Read)    数据从数据库中读取到实体中,在程序运行期间,实体未被修改过的。

2.脏状态(Dirty)    数据从数据库中读取到实体中,在程序运行期间,实体的某些属性被修改过了,这意味着,持久化时

            ,该实体被修改的属性(或者所有属性)的值需要更新到数据库中。

3.删除状态(Delete)  数据从数据库中读取到实体中,在程序运行期间,实体被删除了。这意味着,持久化时,需要在数据库中

           删除对应的记录。

4.销毁状态(Destory) 实体直接在程序中创建并且在程序运行期间被删除的。这意味着,该实体可以直接被丢弃,无需要更新到数据库中。

5.创建状态(New)   实体直接在程序中创建。这意味着,持久化时,应该根据实体的属性在数据库中插入一条记录。

6.所有状态(All)    所有的实体状态。所有状态=读状态|脏状态|删除状态|销毁状态|创建状态

7.当前状态(Current)  实体还仍然存在的一组状态。当前状态=读状态|脏状态|创建状态

数据持久化设计

  将一组属性和方法封装在基类中,所有的实体都继承自该类。基类应该提供的属性和方法如下

Code

 

 

posted @ 2009-09-02 18:36 东风31 阅读(65) 评论(0) 编辑

企业应用的特性

  一、持久化数据的特点

    1.生命周期长。通常比使用这些数据的应用程序的生命周期都长,比硬件、操作系统、编译器都长。

    2.数据本身的结构也会扩展。

    3.数据可能会被迁移到其他系统中去。

  二、大量的数据

  三、许多用户同时访问数据(即并发)。

  四、大量操作数据的用户界面屏幕(为了不同的使用目的,数据需要很多种表现形式)。

  五、要与散布在企业周围的其他企业应用集成。这些各式各样的系统是不同时期、采用不同的技术构建的。甚至连协作机制都不同。

  六、业务的无逻辑性(业务的变化无逻辑)。

每一种特性相当于企业应用的一个维度,这些维度是我们在思考和设计程序架构时所需要考虑的各个方面。

企业应用的种类

  1.用户规模庞大,并随着业务的增长成线性增长(例如b2c的电子商务系统)。

  2.业务逻辑负责(往往UI也很复杂)。

  3.必须快速开发

企业应用的3个基本逻辑

  1.表现逻辑

  2.领域逻辑

  3.数据源逻辑

posted @ 2009-09-02 17:43 东风31 阅读(65) 评论(0) 编辑