성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>Linq To SQL - ALinq Provider를 이용하여 Firebird 사용</div> <br /> 지난번까지 Firebird에 대한 설치 및 ADO.NET 접근 방법을 알아보았는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > .NET 프로그래머에게도 유용한 Firebird 무료 데이터베이스 ; <a target='_tab' href='http://www.sysnet.pe.kr/2/0/1038'>http://www.sysnet.pe.kr/2/0/1038</a> Firebird 데이터베이스와 ADO.NET ; <a target='_tab' href='http://www.sysnet.pe.kr/2/0/1039'>http://www.sysnet.pe.kr/2/0/1039</a> </pre> <br /> 이에 더해서 DB 접근을 너무나 쉽게 해주는 Linq to SQL을 살펴보지 않으면 서운하겠지요. ^^<br /> <br /> 검색을 해보면, 다음의 사이트에서 Firebird 및 기타 데이터베이스들에 대한 "Linq to ..." 제품군을 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > ALinq -- The Best Database Linq Provider ; <a target='_tab' href='http://www.alinq.org/?gclid=CP2D54XF5KgCFc2DpAodRV1uCA'>http://www.alinq.org/?gclid=CP2D54XF5KgCFc2DpAodRV1uCA</a> </pre> <br /> 현재, (2011-05-16) 기준으로 2.5.2 버전을 다운로드해 설치해봤는데요.<br /> <br /> <img alt='fblinq252_1.png' src='/SysWebRes/bbs/fblinq252_1.png' /><br /> <br /> 위에서처럼 단일 설치 파일 내에 Access, DB2, Firebird, MySql, Oracle, PostgreSQL, SQLite에 대한 Linq Provider를 함께 제공하고 있는 것을 볼 수 있습니다.<br /> <br /> 설치하고 나면, C:\Program Files\ALinq 하위에 각각 다음과 같은 폴더 구조가 생성되는데,<br /> <br /> <ul> <li>bin - ALinq Provider DLL 포함</li> <li>samples - C# / VB 예제 파일들</li> <li>share - 개별 DB의 ADO.NET Provider DLL 포함</li> </ul> <br /> bin 폴더 안에, Firebird용으로 ALinq.Firebird.dll이 제공되고 공통 파일로 ALinq.dll 파일이 포함됩니다. 그리고, share 폴더에는 2.5.0 버전의 FirebirdSql.Data.FirebirdClient.dll이 포함되어 있는데 ALinq.Firebird.dll에서 그 2.5.0 버전의 DLL로 강력한 이름(Strong name) 참조를 하고 있습니다.<br /> <br /> 만약, "<a target='_tab' href='http://www.sysnet.pe.kr/2/0/1039'>Firebird 데이터베이스와 ADO.NET</a>" 글에서 살펴본 2.6.0 버전의 FirebirdSql.Data.FirebirdClient를 사용하고 싶다면 어떻게 해야 할까요? 이에 대해 alinq.org 측에 문의를 했더니 support 메일로 다음과 같이 응답이 왔습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > SeongTae Jeong: Yes, you can reference the FirebirdSql.Data.FirebirdClient 2.6.0.0, but you need to append a qualifyAssembly element in the app.config (for win project) or web.confg (for web project). Here is a sample, for more information about qualifyAssembly, please reference MSDN. <?xml version="1.0"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <qualifyAssembly partialName="FirebirdSql.Data.FirebirdClient" fullName="FirebirdSql.Data.FirebirdClient, Version=2.6.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c"/> </assemblyBinding> </runtime> </configuration> I wish my answer can help you. Shu Mai </pre> <br /> 분명히, 예전에 공부했음에도 불구하고 생각이 안 나던 assemblyBinding 정책을 이렇게 다시 한번 배우게 되니... 이젠 정말 잊어버리지 않을 것 같습니다. ^^<br /> <br /> 참고로, 만약 위와 같은 app.config 설정 없이 2.6.0 버전과 사용하면 다음과 같은 오류를 만날 수 있습니다.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: 맑은 고딕, Consolas, Verdana; COLOR: #005555'> An unhandled exception of type 'System.IO.FileLoadException' occurred in ALinq.dll<br /> <br /> Additional information: Could not load file or assembly 'FirebirdSql.Data.FirebirdClient, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)<br /> </div><br /> <br /> <hr style='width: 50%' /><br /> <br /> 굳이, ALinq 제품을 사용하는 모든 컴퓨터에 msi 파일을 이용하여 설치할 필요는 없습니다. 최종적으로 개발자는 다음과 같은 3가지 파일만 복사해 두면 되고, 프로젝트에서는 이를 참조해서 같이 배포해 주기만 하면 됩니다.<br /> <br /> <ul> <li>/bin/ALinq.dll</li> <li>/bin/ALinq.Firebird.dll</li> <li>/share/FirebirdSql.Data.FirebirdClient.dll</li> </ul> <br /> 이제, 코드 작성을 실제로 한번 해볼까요?<br /> <br /> 이번에도 지난번에 작성한 간단한 TESTTABLE 기준으로 코드를 만들어 볼 텐데요. 우선, Console 응용 프로그램을 하나 만들고, .NET 4.0에서 기본 제공되는 System.Data.Linq와 위의 3가지 DLL을 참조 추가 합니다.<br /> <br /> 시작점으로 DataContext를 마련해 두어야 하는데, Firebird용으로 만들면 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > [ALinq.Mapping.ProviderAttribute(typeof(ALinq.Firebird.FirebirdProvider))] public partial class TestDatabaseContext : ALinq.DataContext { public TestDatabaseContext(string connectionString) : base(connectionString) { } } </pre> <br /> 이를 사용하는 간단한 코드를 Main에 넣어두고 실행하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > static void Main(string[] args) { string connectionString = @"DataSource=localhost;Port=3050;Database=c:\temp\test.fdb;User=SYSDBA;Password=masterkey"; TestDatabaseContext dc = new TestDatabaseContext(connectionString); } </pre> <br /> new TestDatabaseContext(...) 실행 지점에서 다음과 같은 오류가 발생합니다. ^^;<br /> <br /> <img alt='fblinq252_2.png' src='/SysWebRes/bbs/fblinq252_2.png' /><br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: 맑은 고딕, Consolas, Verdana; COLOR: #005555'> "<br /> LicenseException was unhandled<br /> <br /> Found license fail!<br /> "<br /> </div><br /> <br /> 그렇습니다. 이 제품은 Trial 버전이라는 중간 단계 없이 처음부터 라이선스를 구매해야 테스트가 되는 제품입니다.<br /> <br /> 가격을 볼까요?<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > ALinq - Purchase ; <a target='_tab' href='http://www.alinq.org/Purchase.aspx'>http://www.alinq.org/Purchase.aspx</a> </pre> <br /> Full Edition으로 구매하는 것은 Single - $299, Team - $899, Site - $2,399이고, Firebird 하나만 구매한다면 Single - $129, Team - $399, Site - $999로 상당히 저렴한 편입니다.<br /> <br /> 사실, 가격은 저렴하지만 이 순간이 가장 고민됩니다. 왜냐하면, 과연 이 제품이 개발을 완료하는 시점까지 나의 요구 사항을 만족할 수 있을지 알 수 없기 때문입니다. (단적인 예로, System.Data.Linq에 포함된 기본 DataContext와 동일하게 기능을 제공할지는 테스트를 해봐야 아는 것입니다.)<br /> <br /> 어쨌든, 라이선스 문제를 해결하고 계속 테스트를 진행해 보겠습니다.<br /> <br /> 지난번에 실습용으로 만들어 둔 TESTTABLE의 테이블 스키마에 알맞게 타입을 생성하고 특성을 적절하게 정의해줍니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > [Table(Name = "TESTTABLE")] public class TestTables { [Column(IsPrimaryKey = true, DbType = "VarChar(50)")] public string Name { get; set; } [Column(DbType = "VarChar(150)")] // Firebird는 NVarChar를 지원하지 않음. public string Description { get; set; } } </pre> <br /> 이어서, TestTables 타입을 DataContext에 추가해주고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > [ALinq.Mapping.ProviderAttribute(typeof(ALinq.Firebird.FirebirdProvider))] public partial class TestDatabaseContext : ALinq.DataContext { ...[생략]... public ALinq.Table<TestTable> TestTables { get { return this.GetTable<TestTable>(); } } } </pre> <br /> 이를 사용하는 간단한 코드를 작성하고 실행해 보면 되겠지요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > static void Main(string[] args) { string connectionString = ConfigurationManager.ConnectionStrings["TestDB"].ConnectionString; TestDatabaseContext dc = new TestDatabaseContext(connectionString); if (dc.DatabaseExists()) { dc.DeleteDatabase(); } dc.CreateDatabase(); TestTable item = new TestTable(); item.Name = Guid.NewGuid().ToString(); item.Description = item.Name + "_Description"; dc.TestTables.InsertOnSubmit(item); dc.SubmitChanges(); var inserted = from record in dc.TestTables where record.Name == item.Name select record; Console.WriteLine(inserted.First().Description); } </pre> <br /> 다행히, 이 정도의 간단한 테스트에는 합격입니다. 좀 더 나아가서, 이번엔 TransactionScope도 테스트해 볼까요? System.Transactions를 참조하고 다음과 같이 코드를 추가합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > using (TransactionScope scope = new TransactionScope()) { dc = new TestDatabaseContext(connectionString); item = new TestTable(); item.Name = Guid.NewGuid().ToString(); item.Description = item.Name + "_Description"; dc.TestTables.InsertOnSubmit(item); dc.SubmitChanges(); // scope.Complete(); } </pre> <br /> 아쉽군요. 결과는 정상적으로 Commit 된 상태를 반환하고 있습니다. 즉 (최소한 Firebird용의) ALinq Provider는 TransactionScope과의 연동에 문제가 있습니다. (같은 코드를 System.Data.Linq의 DataContext로 MSSQL 서버와 연동하면 정상적으로 roll-back 됩니다.) 바로 이런 면들이, trial 단계를 거치지 않고 결제를 했을 때 '향후에 밝혀지는 문제점'들이라고 할 수 있겠는데요.<br /> <br /> 따라서, 불편하게도 ALinq로는 다음과 같이 로컬 트랜잭션을 직접 구동하는 코드를 작성해 주어야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > dc.Connection.Open(); <b style='COLOR: blue'>DbTransaction dbTx = dc.Connection.BeginTransaction(); dc.Transaction = dbTx;</b> item = new TestTable(); item.Name = Guid.NewGuid().ToString(); item.Description = item.Name + "_Description"; dc.TestTables.InsertOnSubmit(item); dc.SubmitChanges(); <b style='COLOR: blue'>dbTx.Rollback();</b> </pre> <br /> 이에 대해, support@alinq.org 측에 문의를 했더니 다음과 같이 답변을 받았습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > The TransactionScope feature is depends on the database. I have google and found it seems not works with firebird database. Here is a sample for you how to use the transaction. using (var conn = new FbConnection(conn_str)) { var dc = new FirebirdNorthwind(conn); conn.Open(); var tran = conn.BeginTransaction(); try { //do something dc.SubmitChanges(); tran.Commit(); } catch { tran.Rollback(); } } </pre> <br /> 그렇군요. 이것은 ALinq 자체의 문제가 아닌, Firebird 데이터베이스 측에서 TransactionScope을 지원하지 않는다고 합니다.<br /> <br /> 어쨌든, ALinq를 다뤄보는 것은 이 정도 선에서 마무리하고... 다음번에는 무료 Linq Provider에 대해서 글을 써보겠습니다. ^^<br /> <br /> (<a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=593&boardid=331301885'>첨부한 파일은 위의 테스트를 담은 프로젝트</a>입니다.)<br /> <br /><br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1071
(왼쪽의 숫자를 입력해야 합니다.)