2011-10-03 21 views
11

Tôi đang phát triển một phần mềm đơn giản sử dụng mã Entity Framework đầu tiên và máy chủ sql nhỏ gọn 4. Tại thời điểm thiết lập này hoạt động. Khuôn khổ thực thể tạo tệp nén máy chủ sql nếu nó chưa tồn tại. Đường dẫn đến cơ sở dữ liệu được định nghĩa từ bên trong một chuỗi kết nối được lưu trữ bên trong tệp app.config. Đó là xây dựng như thế này:Tạo tập tin nhỏ gọn máy chủ sql trong thư mục appdata

<connectionStrings> 
    <add name="DataContext" 
     connectionString="Data source=Database.sdf;" 
     providerName="System.Data.SqlServerCe.4.0"/> 
</connectionStrings> 

Tuy nhiên, tôi muốn đặt cơ sở dữ liệu trong một thư mục trong thư mục Application Data của người dùng hiện tại (C: \ Users \ User \ AppData \ Roaming trên máy win7 của tôi) . Tôi đã thử thiết lập nguồn dữ liệu của chuỗi kết nối thành một cái gì đó như% APPDATA% \ Database.sdf, nhưng điều này không làm việc, tôi nhận được một ngoại lệ "Ký tự không hợp lệ trong đường dẫn" ngoại lệ.

Tôi muốn kết hợp với phương pháp chuỗi kết nối, vì tôi muốn sử dụng một cơ sở dữ liệu khác cho các bài kiểm tra đơn vị của tôi so với ứng dụng thực tế của tôi. Bằng cách này, bạn có thể dễ dàng sửa đổi cơ sở dữ liệu bằng cách đặt một tệp app.config vào thư mục gốc của dự án.

Ai đó có thể hướng tôi đi đúng hướng không?

+0

Nhưng theo cách này tôi phải xây dựng chuỗi kết nối trong mã. Điều này sẽ không làm cho nó dễ dàng chuyển đổi vị trí của cơ sở dữ liệu, như tôi làm bây giờ. Tôi có một tệp app.config riêng biệt trong cả dự án thường xuyên của tôi và dự án thử nghiệm của tôi, cả hai đều trỏ đến một cơ sở dữ liệu khác. –

Trả lời

22

Sử dụng dưới đây:

AppDomain.CurrentDomain.SetData("DataDirectory", Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); 

<connectionStrings> 
    <add name="DataContext" 
     connectionString="Data source=|DataDirectory|Database.sdf;" 
     providerName="System.Data.SqlServerCe.4.0"/> 
</connectionStrings> 
+0

Cảm ơn, công trình này. Ứng dụng thực tế là một ứng dụng wpf và tôi đã đặt dòng AppDomain trong phương thức khởi động App.xaml.cs. –

+0

Bạn được chào đón. –

+4

Bạn cần thêm một đường ống khác trước "DataDirectory" (| DataDirectory |). Chỉ nghĩ rằng điều này có thể giúp ai đó vì tôi đã bị mắc kẹt trong một thời gian! http://msdn.microsoft.com/en-us/library/cc716756(v=vs.100).aspx – Rachel

3
connectionString="Data source=Database.sdf;" 

này cho ứng dụng của bạn để tìm kiếm Database.sdf trong thư mục làm việc hiện tại của ứng dụng của bạn; có thể ở bất cứ đâu và có thể không ghi được. Bạn cần phải xem một vị trí bạn chỉ định:

connectionString="Data source=|DataDirectory|Database.sdf;" 

ADO.NET tìm ký tự ống trong chuỗi kết nối và mở rộng giá trị của thuộc tính của tên đó trong miền của ứng dụng. Vậy giá trị của tài sản DataDirectory là bao nhiêu? Nó phải được thiết lập bởi bất cứ điều gì đã triển khai ứng dụng của bạn:

  • .MSI trình cài đặt được đặt vào thư mục cài đặt ứng dụng. Nếu bạn cho phép người dùng chọn thư mục cài đặt, họ cũng chọn DataDirectory. Đây là lý do tại sao bạn nên luôn sử dụng |DataDirectory| và không bao giờ là đường dẫn mã hóa cứng.
  • ClickOnce xác định thư mục dữ liệu đặc biệt trong dự án của bạn.
  • Ứng dụng web sử dụng thư mục App_Data.
  • Trình gỡ lỗi Visual Studio sử dụng thư mục gỡ lỗi.

Bất kỳ tệp Visual Studio nào trong dự án của bạn có thuộc tính “bản sao vào thư mục đầu ra” sẽ được sao chép vào DataDirectory. Trong hầu hết các trường hợp, DataDirectory sẽ là một thư mục chỉ đọc. Điều này là tốt nếu dữ liệu của bạn là chỉ đọc, nhưng nếu bạn muốn ghi vào nó, bạn sẽ phải sao chép dữ liệu của bạn đến một vị trí có thể ghi. Có lẽ là nơi tốt nhất là Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)). Có một số cách để làm điều này:

  • Nếu bạn đang tạo một tập tin dữ liệu mới có sản phẩm nào, chỉ cần sử dụng API của bạn chuẩn CREATE DATABASE hoặc new SqlCeConnection() hoặc bất cứ điều gì.
  • Nếu bạn muốn bắt đầu với một hạt giống hoặc cơ sở dữ liệu khởi động trước, bao gồm cơ sở dữ liệu hạt giống trong dự án của bạn. Trong quá trình khởi động ứng dụng của bạn, hãy kiểm tra xem cơ sở dữ liệu có tồn tại trong thư mục SpecialFolder.ApplicationData và không, sao chép nó ở đó.

Nếu bạn tìm kiếm mã mẫu trên web để tạo cơ sở dữ liệu cục bộ, bạn sẽ gặp rất nhiều lời khuyên xấu. Đừng làm như sau:

new SqlCeConnection(@"Data source=c:\users\me\myApp\Database.sdf;"); // Do NOT do this! 

Tôi hy vọng tôi không phải giải thích tại sao mã hóa đường dẫn đến dữ liệu của bạn sai; nhưng lưu ý rằng trừ khi bạn chỉ định đường dẫn đầy đủ trong chuỗi kết nối của mình, đường dẫn tương đối với thư mục làm việc hiện tại của bạn.

using (var conn = new SqlCeConnection(@"Data source=|DataDirectory|Database.sdf;")) 
{ 
    conn.Open(); 
    // No No No! This throws an Access Exception for Standard users, 
    // and gets deleted when you repair the app! 
    var cmd = conn.CreateCommand("INSERT INTO Table (column1, column2) VALUES (@p1, @p2)"); 
    ... 
} 

Không được sửa đổi dữ liệu trong DataDirectory. Không chỉ thư mục này không phải lúc nào cũng có thể sửa đổi bởi người dùng, nó được sở hữu bởi trình cài đặt không phải bởi người dùng. Việc sửa chữa hoặc gỡ cài đặt ứng dụng sẽ xóa tất cả dữ liệu của người dùng; người dùng không thích điều đó. Thay vào đó, sao chép dữ liệu đã cài đặt vào một thư mục có thể ghi được bởi người dùng và thực hiện tất cả thay đổi đối với bản sao.

AppDomain.CurrentDomain.SetData("DataDirectory", 
    // Wrong, this overwrites where the user installed your app! 
    Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); 

Không thay đổi giá trị của DataDirectory trong mã của bạn, nó được thiết lập bởi trình cài đặt và nếu bạn thay đổi nó, bạn sẽ không biết nơi dữ liệu của bạn đã được cài đặt. Nếu bạn đang tạo một cơ sở dữ liệu trống, chỉ cần mở nó ở vị trí cuối cùng của bạn. Nếu bạn định tạo bản sao, hãy mở cơ sở dữ liệu đã cài đặt, lưu nó vào vị trí của người dùng, đóng cơ sở dữ liệu đã cài đặt và mở bản sao.

Tôi cũng không khuyến khích lưu dữ liệu vào Environment.SpecialFolder.CommonApplicationData. Điều này có thể không được người dùng ghi và trừ khi có lý do rất tốt, tất cả người dùng phải được phép thay đổi dữ liệu của người dùng khác, mỗi người dùng phải có cơ sở dữ liệu riêng của họ.

Các vấn đề liên quan