My version of SQLite does not support the IF EXISTS operator. How can I drop a table which may or may not exist without getting an error slapped at me?
I can't update the version on a live application right now, so I cannot use a SQLite version that supports IF EXISTS.
The official documentation says to use IF EXISTS, so I suspect your best plan is to upgrade.
If you can't, you need to see whether you can do some trivial operation on the table that will succeed whether or not the table is empty; if it succeeds you should delete the table, if it fails the table is already gone. An example of the sort of operation to try might be:
SELECT COUNT(*)FROM theTable;
Note that you need to trap the possible error from this at the language level, and you might want to wrap the whole lot (probe, error-trap, drop table) in a transaction. Of course, the other approach if you're getting into error handling is to just drop the table and handle the error anyway.
After you created a create script in C#, I think you might want to add rollback transactions, it is safer and it will keep your database from failing, because the data will be committed at the end in one big piece as an atomic operation to the database and not in little pieces, where it could fail at 5th of 10 queries for example.
Example on how to use transactions:
using(TransactionScope tran =newTransactionScope()){//Insert create script here.//Indicates that creating the SQLiteDatabase went succesfully, so the database can be committed.
tran.Complete();}
제네릭 클래스는 특정 데이터 형식과 관련이 없는 작업을 캡슐화합니다.제네릭 클래스는 연결된 목록, 해시 테이블, 스택, 큐, 트리 등의 컬렉션에 가장 일반적으로 사용됩니다.컬렉션에서 항목을 추가하고 제거하는 등의 작업은 저장되는 데이터의 형식과 관계없이 기본적으로 동일한 방식으로 수행됩니다.
컬렉션 클래스를 필요로 하는 대부분의 시나리오에서는 .NET 클래스 라이브러리에서 제공하는 컬렉션 클래스를 사용하는 것이 좋습니다.이러한 클래스 사용에 대한 자세한 내용은 .NET의 제네릭 컬렉션을 참조하세요.
일반적으로 기존의 구체적인 클래스로 시작하여 일반성과 편의성의 균형이 맞을 때까지 형식을 하나씩 형식 매개 변수로 변경하여 제네릭 클래스를 만듭니다.고유한 제네릭 클래스를 만들 때 중요한 고려 사항은 다음과 같습니다.
형식 매개 변수로 일반화할 형식
일반적으로 매개 변수화할 수 있는 형식이 많을수록 코드의 유용성과 재사용 가능성이 향상됩니다.그러나 지나친 일반화는 다른 개발자가 읽거나 이해하기 어려운 코드를 만들어낼 소지가 있습니다.
필요한 형식을 처리할 수 있는 범위 내에서 최대한 많은 제약 조건을 적용하는 것이 좋습니다.예를 들어 제네릭 클래스를 참조 형식으로만 사용하려는 경우에는 클래스 제약 조건을 적용합니다.이렇게 하면 클래스를 값 형식으로 잘못 사용하는 것을 막을 수 있고, as 연산자를 T에 적용하여 null 값 여부를 확인할 수 있습니다.
제네릭 동작을 기본 클래스와 서브클래스로 분할할지 여부
제네릭 클래스는 기본 클래스가 될 수 있으므로 제네릭이 아닌 클래스에 적용되는 디자인 고려 사항이 동일하게 적용됩니다.자세한 내용은 이 항목의 뒷부분에서 설명하는 제네릭 기본 클래스에서 상속하는 데 대한 규칙을 참조하세요.
제네릭 인터페이스를 하나 이상 구현할지 여부
예를 들어 제네릭 기반 컬렉션에 항목을 만드는 데 사용될 클래스를 디자인할 경우 클래스 형식이 T인 IComparable<T>와 같은 인터페이스를 구현해야 할 수 있습니다.
형식 매개 변수와 제약 조건에 대한 규칙은 제네릭 클래스 동작, 특히 상속과 멤버 접근성에 몇 가지 영향을 줍니다.계속하려면 몇 가지 용어를 이해하고 있어야 합니다.제네릭 클래스 Node<T>,의 경우 클라이언트 코드는 형식 인수를 지정하여 폐쇄형 생성 형식(Node<int>)을 만들어 클래스를 참조할 수 있습니다.또는 제네릭 기본 클래스를 지정하는 경우와 같이 형식 매개 변수를 지정하지 않고 개방형 생성 형식(Node<T>)을 만들 수 있습니다.제네릭 클래스는 구체적인 클래스, 폐쇄형 생성 클래스 또는 개방형 생성 기본 클래스에서 상속할 수 있습니다.
삭제 선택된 항목에 대한 비주얼 베이직 도움말 보기 개체 찾아보기 다음 찾기 속성 창 시작 코드창으로 이동하기 중단점 설정/해제 전체선택 복사 파일 추가 메뉴 편집기 찾기 바꾸기 맨앞으로 가져오기 맨뒤로 호출 스택 새 프로젝트 프로젝트 열기 인쇄 프로젝트 탐색기 구성 요소 붙여넣기 조사식 편집 잘라내기 현재줄 잘라내기
전체 컴파일후 시작 커서까지 실행 다음 문 설정 한 단어만 지우기 해당 모듈의 끝으로 이동 해당 모듈의 처음으로 이동 이전 프로시저 선언으로 가기 다음 프로시저 선언으로 가기 한 단어만큼 오른쪽으로 이동 한 단어만큼 왼쪽으로 이동 이전 찾기 속성 페이지 다시 시작 개체 프로시저 단위 실행 간략한 조사식 오른쪽 마우스 버튼 클릭한것과 동일한 효과 오른쪽으로 한 단어 더 선택하기 왼쪽으로 선택된 한 단어 해제하기 위로 한 줄 더 선택하기/지우기 종료 매개 변수 정보 상수 목록 이전 위치 프로시저 나가기 모든 중단점 지우기
C# 5.0부터 비동기 프로그래밍을 보다 손쉽게 지원하기 위하여 async와 await라는 C# 키워드가 추가되었다. async는 컴파일러에게 해당 메서드가 await를 가지고 있음을 알려주는 역활을 하고, await는 awaitable 클래스(즉 GetAwaiter() 라는 메서드를 갖는 클래스)이면 함께 사용되어 awaitable 객체가 완료되기를 기다리는 역활을 한다. 여기서 중요한 점은 await는 UI 쓰레드가 정지되지 않고 메시지 루프를 계속 돌 수 있도록 필요한 코드를 컴파일러가 자동으로 추가한다는 점이다. 메시지 루프가 계속 돌게 만든다는 것은 마우스 클릭이나 키보트 입력, 화면 페인팅 등을 계속 처리할 수 있다는 것을 의미한다. await는 해당 Task가 끝날 때까지 기다렸다가 완료 후, 바로 다음 실행문부터 실행을 계속하는데, 이 때의 쓰레드는 디폴트로 await를 호출하기 이전의 실행 쓰레드가 된다. 즉 UI Thread에서 await를 호출하였다면 await 다음 문장들은 UI 쓰레드에서 실행된다. (Note: 만약 task.ConfigureAwait(false)를 실행하면 쓰레드풀의 쓰레드로 실행된다)
예제
usingSystem;usingSystem.Threading;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceawaitTest{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidbtnRun_Click(objectsender,EventArgse){RunIt();}// async를 붙인다.privateasyncvoidRunIt(){// 긴 계산을 하는 메서드 비동기로 호출Task<double>task=Task<double>.Factory.StartNew(()=>LongCalc(10));// Task가 끝나기를 기다림. 하지만 UI 쓰레드는 Block되지 않는다.awaittask;// Task가 끝난 다음 아래 UI 컨트롤의 값 갱신// 이 문장은 UI 쓰레드에서 실행되므로 Invoke()가 필요 없다.textBox1.Text=task.Result.ToString();}doubleLongCalc(doubler){// 3초간 긴 계산Thread.Sleep(3000);return3.14*r*r;}}}