ASP.NET MVC에서 Linq to Sql 또는 EF(Entity Framework)를 이용해 DataTables를 개발하는 방법에 대해 작성하려 한다.
이 글에서는 Linq to Sql로 설명 하지만, 구현하는 방법은 EF도 크게 다르지 않을것 같다는 생각이 든다.


DataTables를 간단하게 설명하자면 데이터를 테이블로 표현할때 사용되는 jquery 라이브러리로 페이징, 정렬, 검색, 커스터마이징 등 다양한 기능을 지원하여 손쉽게 개발할 수 있다.


Linq to SqlEF의 아주 간단한 차이점을 말하자면 아래와 같다.

1. Linq to Sql은 MS-SQL만 지원하지만 EF는 대부분의 DB엔진을 지원한다.
2. Linq to Sql은 DB First이며, EF는 DB First, Code First 선택 가능하다. (DB First, Code First에 대한 개념은 인터넷을 찾아보세요.)


구현에 앞서 Linq to Sql의 간단한 사용법을 먼저 확인하고 넘어가자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// DB Context 객체 선언
dbDataContext db = new dbDataContext();
 
// 다음과 같은 Query를 Linq로 표현해보자.
// Account라는 테이블에서 전화번호 1111을 포함한 홍길동이라는 사람을 찾는다.
// SELECT * FROM Account WHERE name = '홍길동' AND phone like '%1111%'
// Linq를 사용하는 방법은 크게 두가지가 있다.
 
// 1. 쿼리 형식 (자세한 사용법은 인터넷을 찾아보세요.)
 
// 반환형은 IQueryable<Account>이다.
var data = from d in db.Account
           where d.name == "홍길동" && d.phone.Contains("1111")
           select d;
 
// 2. 함수 형식
// 반환형은 위와 같이 IQueryable<Account>이다.
var data = db.Account.where(a => a.name == "홍길동" && a.phone.Contains("1111"));
cs


DataTables 공식 홈페이지


1. Quick Start
    1) Html을 작성한다.
    2) DataTables의 Javascript, CSS 파일을 CDN 혹은 다운로드 하여 참조 한다.
    3) Javascript 소스에서 DataTables 초기화

* 아래 소스 참조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!-- DataTables CDN -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
 
<table id="table_1">
    <thead>
        <tr>
            <th>col1</th>
            <th>col2</th>
            <th>col3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Row 1 Data 1</td>
            <td>Row 1 Data 2</td>
            <td>Row 1 Data 3</td>
        </tr>
        <tr>
            <td>Row 2 Data 1</td>
            <td>Row 2 Data 2</td>
            <td>Row 2 Data 3</td>
        </tr>
        <tr>
            <td>Row 3 Data 1</td>
            <td>Row 4 Data 2</td>
            <td>Row 5 Data 3</td>
        </tr>
    </tbody>
</table>
 
<script>
    $(document).ready( function () {
        $('#table_1').DataTable();
    });
</script>
cs


! DataTables 사용시 데이터를 어디서 처리하는지에 따라 Client-side와 Server-side로 기능을 구현할 수 있다.


2. Client-side processing
    1)  Client-side의 경우 Quick Start와 동일하다. 
        페이지가 열렸을때 Html Table을 작성한 뒤 Script로 초기화만 하면 끝난다.

* 아래 소스 참조 (ASP.NET MVC Razor 구문을 사용하였다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- DataTables CDN -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
 
<table id="table_1">
    <thead>
        <tr>
            <th>이름</th>
            <th>전화번호</th>
            <th>col3</th>
        </tr>
    </thead>
    <tbody>
        @foreach(var item in Model)
        {
            <tr>
                <td>item.name</td>
                <td>item.phone</td>
                <td>item.address</td>
            </tr>
        }
    </tbody>
</table>
 
<script>
    $(document).ready( function () {
        $('#table_1').DataTable();
    });
</script>
cs


3. Server-side processing (참조 https://datatables.net/manual/server-side)
    1) Server-side의 경우 DataTables의 옵션으로 쉽게 구현이 가능하다.
    2) Server딴에 데이터를 얻어오기 위한 REST를 구현해야한다.


* 구현시 주의 사항
    -> ajax 옵션에서 컬럼을 지정할 수 있다.
    -> 컬럼을 지정하지 않을 시 컬럼 순서대로 데이터가 매칭된다.

* 아래 소스 참조 (Client딴)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!-- DataTables CDN -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
 
<table id="table_1">
    <thead>
        <tr>
            <th>이름</th>
            <th>전화번호</th>
            <th>주소</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>
 
<script>
    $(document).ready( function () {
        $('#table_1').DataTable({
            serverSide: true// Server-side 활성화
            ajax: {
                url: '@Url.Action("GetAccounts")'// 데이터를 얻어오기 위한 EndPoint Url
                type: 'POST'
            },
            columns: [
                { "data""name" },
                { "data""phone" },
                { "data""address" }
            ]
        });
    });
</script>
 
cs


* 아래 소스 참조 (Server딴)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
[HttpPost]
public async JsonResult GetAccounts(DataTablesModel model)
{
    try
    {
        using(dbDataContext db = new dbDataContext())
        {
            var accounts = from d in db.Account
                           where d.name.Contains(model.search.value) && d.phone.Contains(model.search.value)
                           select new 
                           {
                                name = d.name,
                                phone = d.phone,
                                address = d.address
                           };
 
 
            //정렬은 직접 구현해보세요.
            // hint
            // 1. model.order[].column의 값이 정렬할 column 명입니다.
            // 2. model.order[].dir의 값이 정렬 방법입니다. desc or asc
            // 3. 멀티 정렬도 가능합니다.
            
            // 페이징 기능 구현
            int pageLength = model.length == -1 ? accounts.Count() : model.length;
            accounts = accounts.Skip(model.start).Take(pageLength);
 
            return Json(new
            {
                draw = model.draw,
                recordsTotal = db.Account.Count(),
                recordsFiltered = accounts.Count(),
                data = accounts, // 이때 DB에서 Query를 실행하여 데이터를 가져온다.
                error = false
            });
        }
    }
    catch(Exception ex)
    {
        return Json(new
        {
            draw = model.draw,
            recordsTotal = 0,
            recordsFiltered = 0,
            data = "",
            error = ex.ToString()
        });        
    }
}
 
#region DataTables Request Model
public class DataTablesModel
{
    public int draw { get; set; }
    public int start { get; set; } // 시작 페이지
    public int length { get; set; } // 페이지에 보여질 Row의 수
    public List<Column> columns { get; set; }
    public Search search { get; set; }
    public List<Order> order { get; set; }
}
 
public class Column
{
    public string data { get; set; }
    public string name { get; set; }
    public bool searchable { get; set; }
    public bool orderable { get; set; }
    public Search search { get; set; }
}
 
public class Search
{
    public string value { get; set; }
    public string regex { get; set; }
}
 
public class Order
{
    public int column { get; set; }
    public string dir { get; set; }
}
#endregion
cs


끗.

log4net 사용 관련 참고 사이트 : http://hind.pe.kr/1199

log4net 설정 관련 참고 사이트 : http://egloos.zum.com/empty79/v/2956254


C#에서 logging을 할때 손쉽고 편하게 사용할 수 있는 라이브러리를 소개하려한다.

Log4Net이라는 라이브러리 이다.

이 라이브러리는 log4j라는 java라이브러리에서 따온것이라고 알고있다.


log4net에 대한 자세한 내용은 홈페이지를 참조 바랍니다.

https://logging.apache.org/log4net/


1. 사용 방법

 - Nuget으로 Log4Net을 검색하면 아파치 log4net이 제일 상위에 나타난다


 "설치"버튼을 클릭하면 사용준비 끝.


2. 설정 파일

 - 사실 설정 파일에 대해 정확하게 알지 못한다. 일단 구글링을 통해 알아본 기본적인 틀을 확인해보자.

   응용 프로그램의 경우 app.config 파일에 설정 내용을 입력 하지만 나는 asp.net에서 로깅을 하려하기 때문에

   별도의 LogConfig.xml 파일을 생성하였다. (web.config에 하면 되려나)

<log4net>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    <file value="C:\Log\"/>
    <appendtofile value="true"/>
    <datepattern value="yyyy-MM-dd'_Log.log'"/>
    <staticlogfilename value="false"/>
    <rollingstyle value="Date"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionpattern value="%d [%t] %-5p - %m%n"/>
    </layout>
  </appender>
  <root>
    <level value="ALL"/>
    <appender-ref ref="RollingFile"/>
  </root>
</log4net>

<appender> 태그는 로그를 어떤식으로 남길 것인지에 대한 큰 틀이라고 보면된다.

appender 태그 안에서 파일을 어느곳에 만들것인지 파일이름을 어떻게 할것인지 로그 패턴을 어떻게 할것인지를 정할 수 있다.

<root> 태그는 기본 logger 설정을 하며, level 태그는 ALL, Warn, 등등 으로 나뉘며 해당 레벨 이상의 로그만 로그파일에 쓰길 원할경우 설정한다.

appender-ref 태그에는 appender의 name을 입력하여 연결을 해준다.


3. 소스

//using 해준다.
using log4net;
using log4net.Config;

//로깅할 곳에 로그 변수 추가
private ILog _logger = null;
public readonly ILog Logger
{
  get { return _Logger; }
}

string strDirPath;
strDirPath = @"C:\Log";
DirectoryInfo dirInfo = new DirectoryInfo(strDirPath);
//log4net에서 폴더를 만들어주는지 안만들어주는지 몰라서.. 일단 혹시나해서 만듦

if (dirInfo.Exists == false) { if (dirInfo != null) dirInfo.Create(); } //LogConfig.xml 경로를 설정해준다. string AppPath = AppDomain.CurrentDomain.BaseDirectory; //log4net.config 하위의 xmlconfigurator에 설정 파일을 등록한다. XmlConfigurator.Configure(new System.IO.FileInfo(AppPath + @"bin\LogConfig.xml")); //설정파일의 appender의 name에 아까 입력한 RollingFile을 입력하여 logger를 추가한다. _logger = log4net.LogManager.GetLogger("RollingFile"); // ----------- 이렇게 해서 기본적인 변수 선언과 사용준비는 끝. // 사용 //error if(_logger.IsErrorEnabled) _logger.Error("Error!!!!!!!!!!!"); if(_logger.IsDebugEnabled) _logger.Debug("Debug!!!!!!!!!!!"); if(_logger.IsInfoEnabled) _logger.Info("Info!!!!!!!!!!!");

로그를 남길때 수준을 정할 수 있다.

Error, Fatal, Warn, Info, Debug


이렇게 해서 로그 파일을 확인해 보면 아래와 같이 로그가 남는 것을 확인 할 수 있다.



*log4net을 사용하다 보면 남겨야 하는 로그의 성격이 다른 것들이 있다. 이럴경우 로그파일을 나눠서 로그를 남기고 싶을 경우가 있다.

이럴 경우에는 설정파일을 살짝 바꿔서 사용하면된다.


아래와 같이 appender를 추가하고 logger를 추가해주면 끝. 알기쉽게 이름을 잘 지어주면 끝.

눈치가 빠른 사람들은 소스에서 어떻게 사용하는지도 대충은 파악했을 것이다.


<log4net> <appender name="Common" type="log4net.Appender.RollingFileAppender"> <file value="C:\Log\" /> <appendToFile value="true" /> <datePattern value="yyyy-MM-dd'_Common.log'" /> <staticLogFileName value="false" /> <rollingStyle value="Date" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%d [%t] %-5p - %m%n" /> </layout> </appender> <appender name="Socket" type="log4net.Appender.RollingFileAppender"> <file value="C:\Log\" /> <appendToFile value="true" /> <datePattern value="yyyy-MM-dd'_Socket.log'" /> <staticLogFileName value="false" /> <rollingStyle value="Date" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%d [%t] %-5p - %m%n" /> </layout> </appender> <appender name="Database" type="log4net.Appender.RollingFileAppender"> <file value="C:\Log\" /> <appendToFile value="true" /> <datePattern value="yyyy-MM-dd'_Database.log'" /> <staticLogFileName value="false" /> <rollingStyle value="Date" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%d [%t] %-5p - %m%n" /> </layout> </appender> <root> <level value="ALL" /> </root> <logger name="Common"> <level value="ALL" /> <appender-ref ref="Common" /> </logger> <logger name="Socket"> <level value="ALL" /> <appender-ref ref="Socket" /> </logger> <logger name="Database"> <level value="ALL" /> <appender-ref ref="Database" /> </logger> </log4net>

여러 파일에 로그 남기기 소스는 첨부파일을 열어보자

LogManager.cs



'Programming > C#' 카테고리의 다른 글

[C#] 네이버 자동 로그인 / 카페 글쓰기 API  (899) 2019.11.01
[C#]ini file 사용법 & 소스 공유  (540) 2017.01.03
[C#]Snappy 사용법  (143) 2016.12.30
[C#]DataTable Sorting 간단 사용법  (971) 2016.12.30

+ Recent posts