Làm thế nào để join bằng cách sử dụng Key Composite

Ví dụ này cho thấy làm thế nào để thực hiện join các hoạt động mà bạn muốn sử dụng nhiều hơn một khóa chính để xác định một trận đấu. Điều này được thực hiện bằng cách sử dụng một khóa composite. Bạn tạo một khóa composite như là một loại anonymous hoặc tên gõ với các giá trị mà bạn muốn so sánh. Nếu biến query sẽ được chuyển qua các biên giới, phương pháp sử dụng một loại có tên overrides Equals và GetHashCode cho khoá. Tên của các thuộc tính, và thứ tự mà chúng xảy ra, phải được giống hệt nhau trong mỗi khóa.

Ví dụ sau đây cho thấy làm thế nào để sử dụng một khóa composite để join dữ liệu từ ba bảng:

var query = from o in db.Orders from p in db.Products
       join d in db.OrderDetails on new {o.OrderID, p.ProductID} equals new {d.OrderID,
              d.ProductID} into details from d in details
       select new {o.OrderID, p.ProductID, d.UnitPrice};

Các khóa composite phụ thuộc vào tên của các thuộc tính trong các khóa, và thứ tự mà chúng xảy ra. Nếu các thuộc tính trong chuỗi nguồn không có tên giống nhau, bạn phải gán tên mới trong các khóa. Ví dụ, nếu bảng Orders và bảng OrderDetails từng được sử dụng tên khác nhau cho các cột của họ, bạn có thể tạo ra phím composite bằng cách chỉ định tên giống hệt nhau trong các loại anonymous:

join...on new {Name = o.CustomerName, ID = o.CustID} equals
        new {Name = d.CustName, ID = d.CustID }

Làm thế nào để xử lý giá trị Null trong biểu thức truy vấn

 

Ví dụ này cho thấy làm thế nào để xử lý các giá trị null có thể có trong bộ sưu tập nguồn. Một bộ sưu tập các đối tượng đó như là một IEnumerable<T> có thể chứa các yếu tố có giá trị null. Nếu nguồn là một bộ sưu tập vô giá trị hoặc có một phần tử có giá trị null, và query của bạn không xử lý các giá trị null, NullReferenceException sẽ được đẩy ra ngoài khi bạn thực hiện câu truy vấn.

Bạn có thể bảo vệ mã để tránh một ngoại lệ tham chiếu null như trong ví dụ sau đây:

 

var query1 =  from c in categories
       where c != null
       join p in products on c.ID equals
               (p == null ? null : p.CategoryID)
       select new { Category = c.Name, Name = p.Name };

 

Trong ví dụ trước, các nơi mệnh đề lọc ra tất cả các yếu tố null trong thứ tự danh mục. Kỹ thuật này được độc lập của việc kiểm tra null trong mệnh đề join. Các biểu thức điều kiện với null trong ví dụ này hoạt động bởi vì Products.CategoryID là kiểu int? đó là viết tắt cho Nullable<int>.

Trong một mệnh đề join, nếu chỉ có một trong các phím so sánh là một loại giá trị nullable, bạn có thể bỏ các kia với một loại nullable trong biểu thức query. Trong ví dụ sau đây, giả sử là EmployeeID là một cột chứa giá trị kiểu int?:

 

void TestMethod(Northwind db)
{
       var query = from o in db.Orders
              join e in db.Employees
                     on o.EmployeeID equals (int?)e.EmployeeID
              select new { o.OrderID, e.FirstName };
}

 

 

Làm Thế Nào Config Log4Net Trong C#

Log4net là gì?

Log4net là một công cụ giúp người lập trình ghi lại những thông tin trong lúc chạy ứng dụng. Nó chính là một phiên bản chuyển thể từ log4j và vẫn tiếp tục được phát triển kể từ năm 2001. Trong trường hợp ứng dụng của bạn có lỗi mà vẫn không tìm được nguyên nhân, log4net có thể là vị cứu tinh để giúp bạn xác định nơi gây lỗi. Ngoài ra, Log4net còn có thể thay đổi trạng thái log lúc chương trình chạy mà không cần ngừng chương trình. Bên cạnh đó, khi sử dụng log4net sẽ không ảnh hưởng đáng kể đến performance của ứng dụng, log4net còn được thiết kế với tính flexibility rất cao, chúng ta có thể mở rộng và thêm thắt những thứ mình muốn vào thư viện log4net, chẳng hạn như cách thức log, định dạng log,

Sử dụng như thế nào?

Trong bài viết này, tôi sẽ giới thiệu cách sử dụng log4net cho một window application và cách config cho log4net ghi thông tin log ra file bằng một file config. Thực ra đối với web application thì cách sử dụng hoàn toàn tương tự. Chỉ có một số trường hợp file log của bạn không sinh ra được vì không đủ quyền. Như các bạn biết thì Web application chạy dưới 1 process bằng quyền của user ASPNET trong Windows, dó đó nếu user này không đủ quyền ghi file vào folder web của bạn thì file log tương ứng cũng có thể không được tạo ra.

Hãy download version mới nhất của log4net từ website apache. và add reference vào project của bạn như hình sau:

Sau khi bạn đã reference Log4net vào project của mình hoàn chỉnh, các bước còn lại bạn tiếp tục config để project của bạn hiểu Log4Net ở đâu. Để project hiểu bạn cần config code mỗi khi project gọi Log4Net, như vậy thì rất dài dòng và phức tạp vì phải gọi đi gọi lại nhiều lần. Cách đơn giản hãy tạo một class dùng chung và bạn có thể gọi bất cứ đâu mà bạn muốn :

public static class LogService
{
      #region Members
      private static readonly ILog logger = LogManager.GetLogger(typeof(LogService));
     #endregion
      #region Constructors
      static LogService()
     {
          BasicConfigurator.Configure();
          XmlConfigurator.Configure();
     }
     #endregion
     #region Methods   
    public static void WriteLog(LogLevel logLevel, String log)
    {
         if (logLevel.Equals(LogLevel.DEBUG))
             logger.Debug(log);
        else if (logLevel.Equals(LogLevel.ERROR))
            logger.Error(log);
        else if (logLevel.Equals(LogLevel.FATAL))
            logger.Fatal(log);
        else if (logLevel.Equals(LogLevel.INFO))
            logger.Info(log);
        else if (logLevel.Equals(LogLevel.WARN))
            logger.Warn(log);
    }
    #endregion
}

Bây giờ chúng ta đã có class dùng chung trong project của bạn, câu hỏi ở đây là chúng ta sẽ gọi chúng như thế nào? và còn config nào nữa ?. Câu trả lời cho các bạn là còn rất nhiều bạn cứ từ từ và xem tiếp theo. Trước tiên bạn xem project của bạn thuộc một thể loại nào Application hay Web, không sao dù là project nào thì đều có file config riêng cho nó.

Application thì ta có App.config

Web thì ta có Web.config.

Bạn hãy thêm config này vào trong config file của bạn :

Trong file cấu hình này, tôi sử dụng RollingFileAppender. Có rất nhiều loại Appender được xây dựng sẵn trong thư viện log4net. Mỗi loại sẽ có công dụng ghi nội dung log vào một nơi khác nhau. Trong đó RollingFileAppender là được sử dụng nhiều nhất và cũng dễ sử dụng nhất. Tôi sẽ giải thích những gì tôi nghĩ là khó hiểu nhất

<file value="Log4netSampleLog.txt">

Thông tin log của chúng ta sẽ được ghi vào file Log4netSampleLog.txt, file này sẽ nằm ở thư mục chạy của ứng dụng, cùng cấp với file exe và file .config của chúng ta. Nếu muốn nó lưu file vào chỗ khác chúng ta có thể hardcode đường dẫn ở đây.

<maxsizerollbackups value="3" />

Dữ liệu log sẽ được ghi vào file, vì ta đang sử dụng là RollingFileAppender, nên khi kích thước file vượt quá một mức nào đó thì nó sẽ đổi tên file cũ và ghi vào file mới. Tổng số lượng file tối đa sẽ là 10 và những file cũ nhất sẽ bị xóa nếu số lượng file vượt quá 3.

<maximumfilesize value="1MB">

Kích thước file log tối đa sẽ là 1MB.

Layout: Đây là phần khá thú vị, những text log mà chúng ta ghi ra sẽ kèm thêm một số thông tin theo như phần định dạng trong layout như ngày tháng, threadId, className, ... Các bạn có thể tùy biến phần layout này để được log output dễ nhìn nhất.

<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
<layout>

Level: Level mặc định sẽ là Debug cho mọi nơi có sử dụng log trong chương trình của bạn. Nghĩa là nếu bạn khai báo như hình, thì mọi chỗ bạn log đều được ghi xuống file vì level DEBUG là level thấp nhất, nhưng nếu chỗ này bạn để là ERROR thì chỉ có những log với level cao hơn hoặc bằng ERROR mới được ghi xuống file. Khi deploy chương trình cho khách hàng, thường thì chúng ta sẽ để level default là ERROR, khi sử dụng có lỗi ta sẽ yêu cầu khách hàng sử lại thành DEBUG nếu cần thiết.

<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>

- Thông thường người ta sử dụng full name của class (kèm theo đầy đủ namespace) để dùng như loggerName. Cách dùng này rất hợp lý vì chúng ta sẽ biết đoạn log của mình sinh ra từ class.nào. Để ghi Log bạn cần phải xác định rằng bạn ghi cái gì và ghi như thế nào?

Để ghi thông tin bạn làm như sau:

Để ghi lỗi bạn làm như sau :

Còn nhiều và nhiều cách config cho Log4Net bạn có thể tham khao các cách config tại trang wen của nó. 

Chúc bạn thành công.

Cấu hình Log4net như thế nào (Phần 1)?

 

Bài viết này trình bày các cấu hình ví dụ cho việc xây dựng trong appenders. Các cấu hình được thiết kế để làm việc với các log4net.Config.DOMConfigurator và log4net.Repository.Hierarchy.Hierarchy này.

Những ví dụ này không có nghĩa là cấu hình đầy đủ cho các appenders. Đối với một danh sách đầy đủ các thông số có thể thể chỉ định cho từng appender và chi tiết hơn trên mỗi tùy chọn xem tài liệu SDK cho appender này.

AdoNetAppender: Để biết chi tiết đầy đủ xem tham khảo SDK mục: log4net.Appender.AdoNetAppender.

Những cấu hình của AdoNetAppender phụ thuộc vào nhà cung cấp lựa chọn cho các cơ sở dữ liệu mục tiêu. Dưới đây là một số ví dụ.

MS SQL Server: Ví dụ sau đây cho thấy làm thế nào với cấu hình các AdoNetAppender để log tin nhắn với một cơ sở dữ liệu SQL Server. Những sự kiện được viết bằng lô 100 (BufferSize). ConnectionType quy định cụ thể tên kiểu đủ điều kiện cho các System.Data.IDbConnection sử dụng để kết nối với cơ sở dữ liệu. ConnectionString là cơ sở dữ liệu nhà cung cấp cụ thể. CommandText là cả một tuyên bố đã chế biến hoặc thủ tục lưu trữ, trong trường hợp này nó có một prepared statement. Mỗi tham số lập báo cáo hoặc thủ tục lưu trữ được chỉ định bằng tên nó, kiểu cơ sở dữ liệu và cách bố trí mà renders giá trị cho tham số.

Định nghĩa bảng cơ sở dữ liệu có:

CREATE TABLE [dbo].[Log] (
     [Id] [int] IDENTITY (1, 1) NOT NULL,
     [Date] [datetime] NOT NULL,
     [Thread] [varchar] (255) NOT NULL,
     [Level] [varchar] (50) NOT NULL,
     [Logger] [varchar] (255) NOT NULL,
     [Message] [varchar] (4000) NOT NULL,
     [Exception] [varchar] (2000) NULL
)

Những cấu hình appender có:

 

<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
   <bufferSize value="100" />
       <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
       <connectionString value="data source=[database server];initial catalog=[database  name];integrated security=false;persist security info=True;User ID=[user];Password=[password]" />
       <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
       <parameter>
          <parameterName value="@log_date" />
          <dbType value="DateTime" />
          <layout type="log4net.Layout.RawTimeStampLayout" />
       </parameter>
       <parameter>
          <parameterName value="@thread" />
          <dbType value="String" />
          <size value="255" />
          <layout type="log4net.Layout.PatternLayout">
              <conversionPattern value="%thread" />
          </layout>
      </parameter>
      <parameter>
          <parameterName value="@log_level" />
          <dbType value="String" />
          <size value="50" />
          <layout type="log4net.Layout.PatternLayout">
                 <conversionPattern value="%level" />
           </layout>
       </parameter>
       <parameter>
              <parameterName value="@logger" />
              <dbType value="String" />
              <size value="255" />
              <layout type="log4net.Layout.PatternLayout">
                    <conversionPattern value="%logger" />
              </layout>
       </parameter>
       <parameter>
              <parameterName value="@message" />
              <dbType value="String" />
              <size value="4000" />
              <layout type="log4net.Layout.PatternLayout">
                   <conversionPattern value="%message" />
              </layout>
        </parameter>
        <parameter>
               <parameterName value="@exception" />
               <dbType value="String" />
               <size value="2000" />
               <layout type="log4net.Layout.ExceptionLayout" />
         </parameter>
</appender>

 

 

Tìm hiểu về log4net

 

log4net là một công cụ để giúp đỡ các lập trình ghi lại báo cáo và xuất ra một loạt các mục tiêu. Khi có vấn đề với các ứng dụng, nó thật sự hữu ích có thể tìm ra vấn đế một cách chính xác. Với log4net có thể để cho phép đăng nhập tại thời gian chạy mà không sửa đổi các ứng dụng hệ nhị phân. Những gói log4net được thiết kế để báo cáo bản ghi có thể vẫn còn trong mã shipped mà không bị một chi phí hoạt động cao. Khác...