C#2020. 9. 4. 09:29

C#에서 Class를 Dictinonary Key로 사용하는 방법에 대해서 정리를 했다.

 

Dictionary<Class1, Class2> dict = new  Dictionary<Class1, Class2>();

 

 

 

* 위와 같이 Class1을 Key로 사용할려면

public class Class1

{

    public string Value1 { get; set; }

    public int Value2 { get; set; }

 

    public override int GetHashCode()

    {

         return Value1.GetHashCode() + Value2.GetHashCode();

    }

 

    public override bool Equals(object obj)

    {

        Class1 o = obj as Class1;

        return o != null && (o.Value1 == this.Value1 || o.Value2 == this.Value2); 

    }

}

 

- Dictionary에서 Key를 Class로 사용하기 위해서는

 

Key에 해당하는 Class에 GetHashCode()와 Equals(object)를 재정의 해줘야 한다.

 

 

* 사용법 

 

Dictionary<Class1, Class2> dict = new  Dictionary<Class1, Class2>();

 

dict.Add(new Class1() { Value1 = "My Value", Value2 = 1 }, new Class2() {....} );

dict.Add(new Class1() { Value1 = "My Value", Value2 = 2 }, new Class2() {....} );

 

- 위와 같은 형식으로 Dictionary Class를 Key로 사용할 수 있다.

 

 

Class2 c = dict[new Class1() { Value1 = "My Value", Value2 = 1 }] ;

 

dict[new Class1() { Value1 = "My Value", Value2 = 1 }] = new Class2() {...} ;

 

- 위와 같은 형식으로 Dictionary Value를 읽어오고 저장할 수 도 있다.

 

 

Posted by kongzz
C#2017. 11. 8. 15:25

C#의 ToolStripButton 에 Popup 메뉴를 띄워보기 위해서 찾다가 알게 된 내용을 정리하였습니다.

 

 

저장 버튼에 마우스 우클릭시에 위와 같은 Popup 메뉴를 보이게 하기 위하여,

 

해당 ToolStripButton 의 우클릭 이벤트에 아래와 같이

 

ContextMenu에 MenuItem 을 등록하고 Show를 하면 된다.

 

Show에서 마우스 포인터에 Popup Menu를 표시하기 위해서 고생을 했다.

 

 

Posted by kongzz
Oracle2017. 6. 23. 15:18

오라클의 분석함수중에 Lag와 Lead에 대하여 정리해 보았다.

 

select lag(dates, 2) over (order by dates) pprevDate,
       lag(dates, 1) over (order by dates) prevDate,
       dates,
       lead(dates, 1) over (order by dates) nextDate, 
       lead(dates, 2) over (order by dates) nnextDate,
       '' space,
       lag(no, 2) over (order by dates) pprevNo,
       lag(no, 1) over (order by dates) prevNo,
       no, 
       lead(no, 1) over (order by dates) nextNo, 
       lead(no, 2) over (order by dates) nnextNo
  from (
        select no, to_char(sysdate+no,'YYYY-MM-DD') dates 
          from dual,
               (select level no from dual connect by level < 10)
       )

 

 

lag(column_name, n)

  : 현재 row 기준으로 n 개 이전 row 의 값의 column의 값을 표시한다.

 

  ex) lag(no, 2) over (order by dates)

     는 정렬순서는 dates를 기준으로 하여서 no 컬럼의 2번째 앞에 row의 값을 표시하게 하는 함수이다.

 

lead(column_name, n)

  :  현재 row 기준으로 n개 이후 row의 값의 column의 값을 표시한다.

 

  ex) lead(no, 2) over (order by dates)

     는 정렬순서는 dates를 기준으로 하여서 no 컬럼의 2번째 뒤의 row의 값을 표시하게 하는 함수이다.

Posted by kongzz
Oracle2016. 12. 29. 16:23

Oracle 10g 이상에서 V$SESSION에  Client_Info 라는 컬럼이 존재한다.

 

여기에 유용한 Trigger를 하나 적용을 해서 이 컬럼을 아주 유용하고 이용하고 있어 정리해 보았다.

 

 CREATE OR REPLACE Trigger "SYSTEM"."LOGON_AUDIT_TRIGGER"

  after logon on database

begin

    dbms_application_info.set_client_info(sys_context('USERENV', 'IP_ADDRESS'));

end;

 

위의 트리거를 DB에 생성해 놓으면

접속하는 Client 의 ip 정보를 V$SESSION 의 Client_Info라는 컬럼에서 조회해 볼 수 있다.

Posted by kongzz
Oracle2016. 11. 25. 11:55

Database 사용하다가 실수로 Update 나 Delete를 잘못할수도 있다.


Commit을 하였어도 어느 정도의 시간내에서는 시간을 거슬러서 그 시점에서의 Data 상태를 볼수가 있다.


※ 어느 정도의 시간이란 운영중인 DB의 트랜잭션양에 영향을 받기 때문에 그 정도를 가늠하기는 어렵다.


-- 해당 데이터의 10초전 상태를 조회

SELECT * 

  FROM [table_name]

  AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '10' SECOND) 

WHERE [column_name] = '_______'


AS OF TIMESTAMP 문의 위치는 FROM [table_name] 과 WHERE 사이에 위치한다.


-- 해당 데이터의 10분전 상태를 조회

SELECT * 

  FROM [table_name]

  AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '10' MINUTE) 

WHERE [column_name] = '_______'

-- 해당 데이터의 1시간전 상태를 조회

SELECT * 

  FROM [table_name]

  AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' HOUR) 

WHERE [column_name] = '_______'


-- 해당 데이터의 1일전 상태를 조회

SELECT * 

  FROM [table_name]

  AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' DAY) 

WHERE [column_name] = '_______'


또 다른 사용방법은 원하는 시간으로 바로 설정하여 조회할 수 있다.

-- 지정한 시간 시점에서의 데이터 상태를 조회

SELECT * 

  FROM [table_name]

  AS OF TIMESTAMP TO_TIMESTAMP('2016-11-25 10:39:58', 'YYYY-MM-DD HH24:MI:SS') 

WHERE [column_name] = '_______'




* 위의 기본문법으로 아래와 같이 응용을 해볼수도 있다.


- 동일한 데이터를 시간차를 두고 비교를 하는 형식으로도 써보았다.

  두 시간 사이의 데이터 비교도 유용하게 써먹어 본적이 있다.

SELECT .... 

AS OF TIMESTAMP TO_TIMESTAMP('2016-11-25 10:55:58', 'YYYY-MM-DD HH24:MI:SS') 

WHER....

Union All 

SELECT ....

AS OF TIMESTAMP TO_TIMESTAMP('2016-11-25 11:05:10', 'YYYY-MM-DD HH24:MI:SS')

WHER....



- 조회된 데이터를 근거로 현재의 데이터를 다시 Update하거나, 


삭제된 경우라면 

 INSERT INTO [table_name]

SELECT * 

  FROM [table_name]

  AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '10' SECOND) 

WHERE [column_name] = '_______'


 이런 형식으로 데이터를 복구할 수 있다.

Posted by kongzz
C#2016. 11. 23. 11:03

 

C#의 TabControl을 사용하다가 TabPage에 닫기 버튼을 넣고 싶었다.

TabPage라는 단어로 검색을 했더니 TabControl 에서 처리해야 된다는 걸 알게 되었다.

 

TabControl 의 TabPage 에 닫기 버튼을 추가하는 방법에 대한 내용을 정리했다.

 

 

우선 TabControl을 상속을 받는다.

그리고 생성자에서 DrawMode를 OwnerDrawFixed로 해줘야 한다.

 

     public class ucTabControl : TabControl
    {
        private Point _imageLocation = new Point(18, 5);
        private Point _imgHitArea = new Point(15, 3);


        public ucTabControl()
        {
            this.DrawMode = TabDrawMode.OwnerDrawFixed;
        }

 

닫기 버튼에 대한 이미지는 2개를 만들어서 Resource에 만들어 놓았다.

 

하나는 선택된 TabPage의 닫기 버튼을 위한 이미지이며,

다른 하나의 나머지 다른 TabPage의 닫기 버튼을 위한 이미지이다.

 

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            base.OnDrawItem(e);

 

            try
            {
                Image img;          

                Font f = this.Font;

                Rectangle r = e.Bounds;
                Brush titleBrush = new SolidBrush(Color.Black);
                string title = this.TabPages[e.Index].Text;

 

                r = this.GetTabRect(e.Index);
                r.Offset(2, 2);

 

                // SelectedTab의 Background Color 는 White으로 처리
                if(this.SelectedIndex == e.Index)
                    e.Graphics.FillRectangle(new SolidBrush(Color.White), e.Bounds);

 

                // 각 Tab별로 close button 에 대한 image값 
                if (this.SelectedTab == this.TabPages[e.Index])
                    img = Properties.Resources.Close_BWhite;
                else
                    img = Properties.Resources.Close_BGray;

 

                // TabPage Text
                e.Graphics.DrawString(title, f, titleBrush, new PointF(r.X, r.Y));


                // TabPage 의 닫기 버튼
                e.Graphics.DrawImage(img, new Point(r.X + this.GetTabRect(e.Index).Width - _imageLocation.X, _imageLocation.Y));

                img.Dispose();
                img = null;               
            }


            catch (Exception)
            {
            }
        }

 

 

OnDrawItem 메소드 하나만 override 하면 TabPage 별로 닫기 버튼 넣기가 처리가 된다.

 

아래의 그림에서 보면 SelectTab의 닫기버튼은 다른 TabPage 와 배경색이 구분된다.

 

 

 

그런데 문제는 TabControl을 사용해보면 처음 두개의 TabPage 처럼  TabPage Text 와 닫기 버튼이 중첩되어 버린다.

 

this.ucTabControl1.TabPages.Add("New Page3  "); 

 

위와 같은 TabPage 추가시 Text에 공백2개 정도을 추가하면 닫기 버튼 중첩을 회피 할 수는 있다.

 

 

* 위의 내용은 구글 검색중에서 알게 된 내용을 정리하였으며, 출처는 모르겠음.

Posted by kongzz
C#2016. 6. 24. 12:02

C#에서 ADO를 이용하여 Excel 화일 생성하는 기능에 대해서 공부한 내용을 정리를 한 자료입니다.

 

 

1.Connection String 만들기

 

- 확장자가 xls인지 xlsx인지에 따라 Connection String 이 달라진다.

 

 

 

- 해당 Provider의 존재 여부를 레지스트리에서 확인 할 수가 있다.

 

 

 

 

2. DataGridView에 있는 데이터를 Excel 생성하는 예제.

 

 

- CREATE 문 생성시 특이사항.

  NAME, ADDR 은 VARCHAR로 생성하였고,
  MEMO 는 MEMO로 생성하였다.

  VARCHAR은 255byte 의 제약이 있다.

  MEMO 의 제약은 얼마인지는 모르겠다.

 

 

 

- 이렇게 호출하면 Excel이 설치되지 않은 컴에서도 Excel화일이 생성된다.

Posted by kongzz
NAS2015. 8. 3. 14:23

NAS를 살 때 많은 고민을 하고 Synology 제품을 선택했다.

FTP 같은 기능은 당연한 것이고,

CloudStation 은 참 만족스러운 기능으로 사용을 했다.

 

최근에 주변 사람을 통해서 소스 형상관리툴 Git을 알게 되었다.

나의 NAS에서 Git을 설치할 수 있다는 것을 알게 되고는

구글링등의 많은 방법을 통하여 설치하는 방법을 알게 되었다.

 

이걸 정리를 해 놓아야지 다음에 다시 설치하더라고 유용할꺼 같아서 정리를 해 보았다.

 

● 설치 환경

Synology NAS DS212J

DSM 5.2

 

● 사용환경

Visual Studio 2013

 

● 설정방법

 

1.NAS에서 SSH서비스를 활성화해야 한다.

 

제어판에 들어가서 응용 프로그램란에 [터미널 및 SNMP]를 선택한다. 

 

 

SSH 서비스를 활성화 시켜준다. 

 

 

2.Git Server 설치

 

NAS바탕화면에 있는 패키지 센터를 실행해서, [모두] 또는 [유틸리티]화면을 열어보면 아래와 같이 Git Server라는게 보인다.

서버가 설치되기 전에는 버튼이 [설치]라고 되어 있어 설치하고 나서 보면 아래와 같이 [열기]로 보여진다. 

 

 

Git Server 설치 후 설치됨 메뉴를 선택해보면 아래와 같이 설치가 되었음을 알 수가 있다.

 

 

Git Server를 선택하여 들어가서 Git Server 서비스를 활성화 시켜준다. 

 

 

3.NAS에 사용자 계정을 추가해야 한다.

 

다시 제어판에 가서 사용자 메뉴를 선택한다.

사용자 메뉴에서 [생성] 버튼을 클릭한다.

 

 

사용자 정보를 입력한다.

사용자 계정을 gituser라고 했다.

 

 

gituser의 그룹은 users로 선택한다.

 

 

gituser는 homes만 접근권한을 줬다.

 

 

그 이후는 모두 다음 .. 다음 넘어가면 되고 혹시나 싶어서 WebDav는 허용하였다. 

 

 

 

4.Repository 생성

 

NAS에서의 작업은 끝이 난거 같다.

Windows 를 사용하는 관계로 PuTTY를 이용해서 Repository를 생성해야 되겠다.

PuTTY를 실행하고 root로 로그인을 한다.

 

 


DSM 버젼이 올라가면서 root로 로그인이 안된다.

  admin 계정으로 로그인을 하고

  sudo -i 를 입력하여서 (패스워드는 admin 계정 패스워드와 동일) 작업을 진행해야한다. 

 


 

키보드를 두드릴 시간이 왔다.

 

NAS에 disk가 하나가 있어 그 놈은 volume1인데 그 놈의 이름이 /var/services 이라는것 같다.(리눅스를 잘 모름)

아뭏튼 gituser라고 만든 계정의 홈은 /var/services/homes/gituser가 된다.

 

여기에 project.git 이라는 폴더를 생성고

그 폴더로 들어가서 Repository 초기화(?)라나 뭐 그렇게 해준다.

그리고 cd .. 하여 상위 폴더로 올라와서

project.git 이란 폴더의 하위 전체의 권한을 gituser에 넘긴다.

 

chown -R (git사용자 계정):(git 사용자가 속한 그룹)  (사용자 디렉토리)

 

여기까지 하면 Git Server의 설정이 끝이다.

 

 

 

5.Windows 에서의 설정

 

이것도 참 고생을 했다.

개념 모르고 덤비니 가시밭길이 이만 저만이 아니다.

그래도 다 왔다.

 

참고로 Windows에서의 Git 에 대한 사용법은 http://backlogtool.com/git-guide/kr/ 여기를 참고했다.

 

TortoiseGit 프로그램을 설치를 한다.

그리고 나서 Windows 원하는 경로에 repository를 생성한다.

 

 

 

그리고는 다시 TortoiseGit의 Settings 화면에서 사용자를 저장한다.

이 때 사용자는 NAS에 만든 gituser가 아닌 개발자를 의미한다.(개발자마다의 개별 설정)

 

 

제일 중요한 마지막 설정이다.

URL 은 http로는 성공을 못했다. 그래서 ssh로 했다.

ssh://(NAS에 생성했던 계정)@(NAS의 DNS):(포워딩한 port)/volume1/homes/(사용자 계정 폴더)/(Repository 폴더 명)

(예 ssh://gituser@nas.familyds.com:9112/volume1/homes/gituser/project.git)

 

- ssh의 표준 포트는 SSH 서비스 활성화에서처럼 22이다.

  세상이 무서워서 port forwading을 하는게 좋을꺼 같다. 임의의 숫자로

 

- /volume1 대신 /var/services 라고 써도 되는거 같은데 다음에 설정할 일이 있으면 그렇게 해 보아야겠다.

 

 

 

이렇게 해서 NAS에서의 Git 사용에 관련된 모든 설정을 완료한거 같다.

많은 시간을 들여서 해 놓은 삽질을 잊어버리기 전에 이렇게 정리한 번 해 보았다.

 

Posted by kongzz
Windows2015. 7. 28. 16:23


msdaora.reg


거래처에서 잘 사용하던 프로그램이 어느 날부터 안된다고 하였다. 

[소프트웨어 개발환경 : vb6, Oracle]

[사용자 환경: Windows 8.1 64bit]


오라클도 새로 설치하고, 응용 프로그램들도 새로 설치해 보고 그래도 안되었다.

VB로 개발된 프로그램은 오라클에 접속이 안 되어도,

C#으로 개발한 프로그램을 정상으로 오라클 접속이 가능했다.


차이점은 VB는 Ado를 사용했고, C#은 System.Data.OracleCleint를 사용한것이다.


그래서 거래처 PC를 몇 시간 뒤지고 이상한 내용을 찾았다.




구글에서도 'e8cc4cbe-fdff-11d0-b865-00a0c9081c1d' 이러한 키 값으로 조회가 된다.


많은 영어들 속에서 이건 문제가 있는게 맞는거 같았다.


그 때는 방법을 몰라서 OS 재설치하시라고 했었다.


그 이 후 오늘 다른 거래처에서 Windows 8.1(64bit) 컴에서 또 다시 동일한 현상이 발생하였다.


혹시나 해서 내 자리 Windows 8.1에서 해당 키 값을 추출했다. 

파일이름은 msdaora.reg라고 정했다.

그 파일을 넘겨서 적용시켜 보았다.


프로그램이 정상적으로 동작하였다.


모든 프로그램이 정상적으로 동작했다.


구글에서도 저 키값으로 구글링을 하는 사람들이 있는 가보던데 

이런 황당한 일을 오늘 난 한 건 해결했다.



'Windows' 카테고리의 다른 글

SSD 스토리지 수명을 늘리는 방법  (0) 2014.08.29
Windows 제어판 명령어  (0) 2013.09.30
Posted by kongzz
C#2015. 7. 25. 13:43

 

C#으로 만든 Oracle Database 조회 프로그램입니다.

toad의 Schema Browser 같은 화면을 만들어 보았습니다. 


 

- 개발환경:

Visual Studio 2015

.Net Framework 2

Oracle 32bit 접속 환경

실행화일은 500K 미만의 작은 소형 프로그램입니다.

 

Windows XP에서는 .Net Framework 2를 설치후 사용 가능하며,

Widows 7이상의 환경에서는 .Net Framework 2가 기본으로 있어서

 오라클Client 가 설치된 환경에서는 실행 화일 하나만으로 실행이 가능합니다.

 

 

- 아래와 같은 기능들이 있습니다.

 

 [쿼리 조회 기능]

 F1 키를 이용하면 몇가지 기능에 대한 Help를 볼 수 있습니다.

 


[Schema Browser]

 

 

[Tablespace Viewer]

 


 

 

 * 첨부화일

DBViewer.exe
0.46MB

Posted by kongzz