2009-08-19 33 views
41

Tôi muốn lưu một đối tượng (thuộc bất kỳ loại nào) vào một trường trong cơ sở dữ liệu trong SQL Server 2005. Có thể không? Tôi có phải chuyển đổi các đối tượng thành một cái gì đó, giống như một mảng byte ví dụ và đúc nó trở lại khi lấy nó?Tôi có thể lưu 'Đối tượng' trong cơ sở dữ liệu SQL Server không?

+2

Bạn cũng có thể serialize ra XML mà sẽ dễ dàng hơn để kiểm tra bên trong db hơn dữ liệu nhị phân – pjp

+1

Nó không phải là một thiết kế DB tuyệt vời. Bạn sẽ cần phải truy vấn các thuộc tính của đối tượng tại bất kỳ điểm nào? ví dụ. nhận được tất cả các đối tượng nơi object.Foo = 1. – Paddy

+0

Không, tôi không cần phải biết hoặc truy vấn nội dung của các bảng được lưu trữ –

Trả lời

27

Bạn có thể sử dụng các loại VARBINARY(MAX) trường trong SQL Server, nếu bạn muốn. Bạn có thể lưu trữ bất kỳ loại đối tượng nào trong đó, có kích thước tối đa là 2 GB.

Để truy cập vào nó, bạn có thể sử dụng ADO.NET - một cái gì đó như thế này:

object yourMysteryObject = (whatever you like it to be); 

MemoryStream memStream = new MemoryStream(); 
StreamWriter sw = new StreamWriter(memStream); 

sw.Write(yourMysteryObject); 

SqlCommand sqlCmd = new SqlCommand("INSERT INTO TableName(VarBinaryColumn) VALUES (@VarBinary)", sqlConnection); 

sqlCmd.Parameters.Add("@VarBinary", SqlDbType.VarBinary, Int32.MaxValue); 

sqlCmd.Parameters["@VarBinary"].Value = memStream.GetBuffer(); 

sqlCmd.ExecuteNonQuery(); 

Marc

+0

nhưng làm thế nào tôi có thể chuyển một đối tượng vào một loại VARBINARY? –

+0

nhưng đây là một hình ảnh được đọc từ một tệp. Nếu tôi có một lớp hoặc một đối tượng được tạo ra trong thời gian chạy. Không có gì để làm với các tập tin. –

+0

bất kỳ loại đối tượng nào có thể được ghi vào MemoryStream và do đó được gán cho giá trị của SqlParameter mà sau đó sẽ ghi nó vào cơ sở dữ liệu. –

1

Để thực hiện việc này, bạn cần phải sắp xếp lại đối tượng của mình. Bạn có thể tìm kiếm ở đây tại ví dụ:

http://www.c-sharpcorner.com/UploadFile/bipinjoshi/serializingObjectsinCS11102005234746PM/serializingObjectsinCS.aspx

+1

Nhưng tôi không muốn lưu nó trên đĩa cứng. Tôi chỉ muốn đặt nó vào một databse. –

+10

BinaryFormatter là một lựa chọn ** rất xấu ** để lưu trữ lâu dài. –

10

Như những người khác đã nói, serialization thể là chìa khóa ở đây (giả sử bạn không muốn sử dụng ORM để lưu trữ các thuộc tính dưới dạng các cột trong bảng, có vẻ trực tiếp hơn nhiều).

Một số cảnh báo mặc dù; một cơ sở dữ liệu là:

  • lưu trữ lâu dài
  • không liên quan đến mã NET của bạn

Như vậy, bạn không muốn sử dụng bất kỳ kỹ thuật serialization đó là nền tảng cụ thể hoặc phiên bản -riêng. Bạn sẽ thường thấy mọi người đề cập đến số BinaryFormatter cho sự kiên trì, nhưng điều này rơi vào cả hai bẫy trên. Bạn sẽ bị lừa đảo nếu bạn thay đổi nền tảng, hoặc thậm chí nếu bạn chỉ cần change some properties.

Bạn cần một cách tiếp cận độc lập với triển khai; đơn giản nhất (cũng có khả năng đọc được con người) là xml hoặc json, có lẽ thông qua XmlSerializer hoặc Json.NET (được lưu trữ trong một [n]varchar(max)). Nếu bạn không quan tâm đến con người có thể đọc được, "bộ đệm giao thức" (nhanh/nhị phân) sẽ hoạt động tốt (được lưu trữ trong một varbinary(max)), và là available for most platforms (bao gồm C# /. NET/etc).

17

Tôi sẽ sử dụng JSON để chuyển đổi đối tượng thành chuỗi và lưu trữ nó trong trường VARCHAR hoặc TEXT. Không chỉ dữ liệu được lưu trữ ở định dạng có thể đọc được của con người, nhưng nó cũng có thể đọc được từ các ngôn ngữ khác nhau, vì hầu hết mọi ngôn ngữ chính thống đều có sẵn một trình phân tích cú pháp JSON.

Liên kết tôi đăng có liên kết tới một số thư viện bằng nhiều ngôn ngữ (bao gồm cả C#), tôi đã sử dụng this one một vài lần trong quá khứ.

+0

Thật không may, bây giờ bạn có liên kết chết đến trang web này. http://jayrock.berlios.de/ –

+0

Cảm ơn, đã cập nhật liên kết. – Badaro

10

Dưới đây là một ví dụ nếu bạn đang sử dụng Entity Framework (EF):

  using (DbContext db = new DbContext()) 
      { 
       // The object that you want to serialize. In this case it is just an empty instance 
       YourObject objectToSerialize = new YourObject(); 
       IFormatter formatter = new BinaryFormatter(); 
       using (MemoryStream stream = new MemoryStream()) 
       { 
        formatter.Serialize(stream, objectToSerialize); 

        // EF model. In one of its properties you store the serialized object 
        YourModel modelObject = new YourModel(); 

        // In your model 'SerializedObject' should be of type byte[]. In the database it should be of type varbinary(MAX) 
        modelObject.SerializedObject = stream.ToArray(); 
        db.YourModel.Add(modelObject); 
        db.SaveChanges(); 
       } 
      } 

Và đây là cách để de-serialize các đối tượng:

// De-serialize 
      IFormatter formatter = new BinaryFormatter(); 
      Stream stream = new MemoryStream(serializedObject); 
      YourObject deserializedYourObject = (YourObject)formatter.Deserialize(stream); 
      stream.Close(); 
+0

Làm thế nào để bạn đưa nó trở lại đối tượng chúng tôi vừa lưu ... biết rõ đối tượng ban đầu là gì. – ppumkin

+1

@ppumpkin. Tôi đã cập nhật câu trả lời của tôi với thông tin làm thế nào để de-serialize đối tượng. Mã hóa hạnh phúc :) –

+0

Lớp đang được tuần tự hóa phải được đánh dấu bằng thuộc tính Serializable. – Elton

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