Mam interesujący problem z obsługą 8-bitowych znaków "ASCII" w LINQ-to-Entities i mam nadzieję, że ktoś może dać mi napiwek.LINQ-to-Entities z 8-bitowymi danymi ASCII
Odziedziczyłem bazę danych SQL Server 2000, która ma kilka pseudo-zaszyfrowanych kolumn, gdzie po prostu XOR'd ciąg znaków z 0xFF
. Nie wiem dlaczego i wiem, że to kiepskie, ale to jest miejsce, w którym teraz jesteśmy.
Te kolumny mają typ danych SQL char(7)
i char(14)
. Kiedy używasz XOR przy użyciu 0xFF
, otrzymujesz zestaw 8 bitów w każdym przypadku, więc kończysz na znakach spoza ASCII (i tak przez Microsoft). UTF-8 wydaje się być tutaj wskazany, ale dekodowanie zostaje pomieszane.
Jestem w stanie odczytać i rozszyfrować te ciągi następująco:
- Get pola przy użyciu LINQ jako
String
. - Get
byte[]
korzystającSystem.Text.Encoding.GetEncoding(1252).GetBytes()
- Decode przez XORing każdy bajt z
0xFF
- Return zdekodowany ciąg z
System.Text.Encoding.GetEncoding(1252).GetString()
Działa to doskonale.
Problem polega na tym, że nie mogę wstawić łańcucha ENCODED do SQL Server używając LINQ.
ja po prostu proces odwrotny i robie:
- Uzyskaj bajty za pomocą
ASCIIEncoding.GetBytes()
. (Nie ma potrzeby stosowania CodePage 1252 tutaj, ponieważ jest to prosty ciąg znaków). - Zakoduj bajty za pomocą
0xFF
. - Powrócić kodowany ciąg znaków za pomocą
GetEncoding(1252).GetString()
.
Jeśli spojrzę na mój sznur, to dokładnie to, czego bym się spodziewał. Ale jeśli wypchnę to w mojej jednostce i wykonam numer SaveChanges()
, wynikowa wartość w Serwerze SQL będzie zawsze wynosić "?????"
o pewnej długości.
Jestem pewien, że czegoś tu nie ma, ale próbowałem wszystkiego, co mogę wymyślić i nie mogę tego zdobyć. Na razie po prostu wróciłem do staroświeckiego sposobu używania SqlCommand
i wykonałem UPDATE z kodowanymi łańcuchami jako SqlParameters
. Nie ma problemu, działa za każdym razem.
Z góry dziękujemy za wszelką pomoc.
Aktualizacja:
Próbowałem sugestię JamieSee i nie jestem nawet uzyskanie dobrej dekodowanie z jego metodą. Mam:
static void Main(string[] args)
{
Encoding characterEncoding = Encoding.GetEncoding(28591);
HCBPWEBEntities ent = new HCBPWEBEntities();
var encUser =
(from users in ent.tblEmployer
where users.ipkEmpId == 357
select users.sKey).First();
Console.Out.WriteLine("Original XOR Encoded PW: {0}", encUser.ToString().Trim());
byte[] originalBytes = (from character in characterEncoding.GetBytes(encUser.ToString().Trim())
select (byte)(character)).ToArray();
Console.Write("Original Bytes:\t");
foreach (byte b in originalBytes)
{
Console.Write("{0:x} ", b);
}
Console.WriteLine(String.Empty);
byte[] decodedBytes = (from character in characterEncoding.GetBytes(encUser.ToString().Trim())
select (byte)(character^0xFF)).ToArray();
Console.Write("Decoded Bytes:\t");
foreach (byte b in decodedBytes)
{
Console.Write("{0:x} ", b);
}
Console.WriteLine(String.Empty);
string decoded = characterEncoding.GetString(decodedBytes);
Console.WriteLine("Decoded PW: {0}", decoded);
ent.Dispose();
}
Ale wynik tego są:
Original XOR kodowane PW: z?O> oryginalne Bytes: 7a 9d 6f 3e dekodowane bajtów: 85 62 90 c1 Decoded PW: B A
Hasło jest faktycznie "abcd"
Proszę przechwytywania SQL wykonywanego przez L2S pomocą SQL Profiler i po to. (Bardzo łatwo to zrobić.) – usr
Używam LINQ-to-Entities, a nie LINQ-SQL, ale przechwytywanie SQL za pomocą Profiler jest dobrym pomysłem. Ustawię to i zobaczę, co mówi. Ale domyślam się, że pokaże, że SQL przechowuje dokładnie to, co ma przechowywać. Naprawdę uważam, że problemem jest mapowanie znaków spoza ASCII z Entity FW na SQL. – user1536209
Jaka jest twoja kolekcja dla danej bazy danych? Możesz go znaleźć za pomocą 'SELECT collation_name FROM sys.databases WHERE name = 'mydatabase''. – JamieSee