Chcę zapisać obiekt (dowolnego typu) w polu w bazie danych w SQL Server 2005. Czy to możliwe? Czy muszę przekonwertować obiekt na coś, na przykład na tablicę bajtów i odrzucić go podczas pobierania?Czy mogę zapisać "Obiekt" w bazie danych SQL Server?
Odpowiedz
Można użyć typu VARBINARY(MAX)
pola w SQL Server, jeśli chcesz. Możesz tam przechowywać dowolny typ obiektu o rozmiarze do 2 GB.
Aby uzyskać do niego dostęp, można użyć ADO.NET - coś takiego:
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
ale jak mogę przenieść obiekt do typu VARBINARY? –
, ale jest to obraz odczytany z pliku. Co jeśli mam klasę lub obiekt utworzony w czasie wykonywania? Nic wspólnego z plikami. –
każdy typ obiektu można zapisać do obiektu MemoryStream, a tym samym przypisać mu wartość parametru SqlParameter, który następnie zapisze go w bazie danych. –
Aby to zrobić, musisz serializować obiekt. Możesz zajrzeć tutaj w przykładach:
Ale nie chcę zapisywać go na dysku twardym. Po prostu chcę umieścić go w databse. –
BinaryFormatter jest ** bardzo złym wyborem ** do długoterminowego przechowywania. –
Jak mówili inni, serializacji może być kluczem tutaj (zakładając, że nie chce użyj ORM, aby przechowywać właściwości jako kolumny w tabeli, co wydaje się dużo bardziej bezpośrednie).
Niektóre zastrzeżenia; baza danych jest:
- przechowywanie długoterminowe
- niezwiązane z kodem .NET
Jako takie, ty nie chcesz użyć dowolnej techniki serializacji, który jest przeznaczony dla konkretnej platformy lub wersja -konkretny. Często widzisz, że ludzie wspominają o braku zaufania, ale dotyczy to obu powyższych pułapek. Zostaniesz oszukany, jeśli kiedykolwiek zmienisz platformę lub nawet po prostu change some properties.
Potrzebujesz podejścia niezależnego od wdrożenia; najprostszym (który zachowuje również zdolność do czytania w języku ludzkim) jest xml lub json, być może przez XmlSerializer
lub Json.NET (przechowywany w [n]varchar(max)
). Jeśli nie dbasz o czytelność czytelną dla człowieka, "bufory protokołów" (szybkie/binarne) dobrze by działały (przechowywane w varbinary(max)
) i są available for most platforms (w tym C#/.NET/etc).
Chciałbym użyć JSON, aby przekonwertować obiekt na ciąg i zapisać go w polu VARCHAR lub TEXT. Nie tylko dane są przechowywane w formacie czytelnym dla człowieka, ale można je również odczytać z różnych języków, ponieważ prawie każdy język głównego nurtu ma dostępny parser JSON.
Opublikowany przeze mnie link zawiera linki do kilku bibliotek w wielu językach (w tym w języku C#), kilka razy używałam this one.
Niestety masz teraz martwe linki do tej strony. http://jayrock.berlios.de/ –
Dzięki, link zaktualizowany. – Badaro
Oto przykład, jeśli używasz 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();
}
}
I to jest jak de-serializacji obiektu:
// De-serialize
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(serializedObject);
YourObject deserializedYourObject = (YourObject)formatter.Deserialize(stream);
stream.Close();
Jak odrzucić to z powrotem do obiektu, który właśnie uratowaliśmy ... wiedząc, co pierwotnie było oczywiste. – ppumkin
@ppumpkin. Zaktualizowałem swoją odpowiedź z informacją, jak odserializować obiekt. Szczęśliwe kodowanie :) –
Klasyfikująca się klasa musi być oznaczona atrybutem Serializable. – Elton
Można również serializowania się do XML, które byłoby łatwiej sprawdzić wewnątrz db niż dane binarne – pjp
To nie jest świetny projekt DB. Czy w dowolnym momencie będziesz musiał zapytać o atrybuty obiektu? na przykład uzyskać wszystkie obiekty, w których object.Foo = 1. – Paddy
Nie, nie potrzebuję znać lub zapytać o zawartość tabel przechowywanych –