In diesem Unittest werde ich überprüfen, dass das MD5 der Content-Byte-Spalte berechnet, persistent ist und korrekt abgerufen wird.Entity Framework Kontext 6.1.3 nicht aktualisiert/zerstört?
Es scheint jedoch, dass der Entity Framework (6.1.3) -Kontext nicht aktualisiert/zerstört wird, da nach dem rohen SQL-UPDATE eindeutig, aber nicht beim Abrufen der Zeile mit einem neuen Kontext wirksam wird.
namespace UnitTests
{
[TestClass]
public class TestDataPacketServiceDebug
{
[TestInitialize]
public void Setup()
{
CommonMethods.ResetDatabase();
try
{
CommonMethods.ResetDataPacketDirectory();
}
catch (DirectoryNotFoundException)
{
}
}
[TestCategory("DataPacketService"), TestMethod]
public void TestGetLocalFilePathDebug()
{
// Persist a DataPacket
int dataPacketId;
using (var testDBContext = new TestDBContext())
{
DataPacket dataPacket = new DataPacket
{
Content = File.ReadAllBytes(@"Resources\SampleResources.zip"),
Description = "DataPacketSample consist of some random found .DLL files on disk",
Name = "SampleResources",
Version = "1"
};
testDBContext.DataPackets.Add(dataPacket);
testDBContext.SaveChanges();
dataPacketId = dataPacket.DataPacketId;
}
// Verify file path extraction
using (var testDBContext = new TestDBContext())
{
DataPacket dataPacket = DataPacketService.GetByNameAndVersion("SampleResources", "1",
testDBContext);
string extractedFilePath = DataPacketService.GetLocalFilePath(testDBContext,
dataPacket, "EntityFramework.dll");
string validDestinationPath = String.Format(@"{0}\DataPackets\{1}_v{2}\EntityFramework.dll",
AppDomain.CurrentDomain.BaseDirectory, dataPacket.Name, dataPacket.Version);
Assert.AreEqual(validDestinationPath, extractedFilePath);
if (File.Exists(extractedFilePath) == false)
{
Assert.Fail("SampleResources was not extracted correctly");
}
}
// When setting a breakpoint here and take a look with external SQL Browser
// (e.g. Microsoft SQL Server Management Studio), following is in order:
// Note! Not all columns are shown
// -----------------------------------------------------------------------------------------------
// DataPacketId | Name | RowVersion | Content | MD5 | Version
// 1 | SampleResources | NULL | 0x504B03... | 2zSV8IChaiyf0UfnezDHKg== | 1
// Manually modify MD5 field in database for MD5 verification
using (var testDBContext = new TestDBContext())
{
string sqlUpdate = String.Format("UPDATE dbo.DataPackets SET MD5 = 'another_MD5' WHERE DataPacketId = {0}",
dataPacketId);
testDBContext.Database.ExecuteSqlCommand(sqlUpdate);
}
// When setting a breakpoint here we can clearly see that the row has been changed:
// Note! Not all columns are shown
// ----------------------------------------------------------------------------------
// DataPacketId | Name | RowVersion | Content | MD5 | Version
// 1 | SampleResources | NULL | 0x504B03... | another_MD5 | 1
// Verify MD5
using (var testDBContext = new TestDBContext())
{
// Fetch dataPacket with modified MD5
DataPacket dataPacket = DataPacketService.GetByNameAndVersion("SampleResources", "1", testDBContext);
// Verify that the raw SQL command has been successful:
Assert.AreEqual("another_MD5", dataPacket.MD5);
// BANG!!!!!!!!!!!!!!
// Result Message: Assert.AreEqual failed. Expected:<another_MD5>.Actual:<2zSV8IChaiyf0UfnezDHKg==>.
}
}
}
}
Entity:
public class DataPacket
{
/// <summary>
/// Identifier
/// </summary>
public int DataPacketId { get; set; }
/// <summary>
/// Concurrency Token
/// </summary>
public byte[] RowVersion { get; set; }
/// <summary>
/// Name
/// </summary>
public string Name { get; set; }
/// <summary>
/// Description of data packet
/// </summary>
public string Description { get; set; }
/// <summary>
/// Version of data packet
/// </summary>
public string Version { get; set; }
/// <summary>
/// MD5 of the data packet (i.e. MD5 of Content byte array)
/// </summary>
public string MD5 { get; private set; }
private byte[] content;
/// <summary>
/// Byte content of the data packet (i.e.
/// </summary>
public byte[] Content
{
get { return content; }
set
{
content = value;
UpdateMD5();
}
}
/// <summary>
/// TestCase navigation DataPacket <== One-To-Many ==> TestCases
/// </summary>
public ICollection<TestCase> TestCases { get; set; } // DataPacket <== One-To-Many ==> TestCases
/// <summary>
/// Update MD5 checksum depending on content
/// </summary>
private void UpdateMD5()
{
if (content != null)
{
this.MD5 = GetMD5ForBytes(content);
}
}
/// <summary>
/// Get MD5 checksum for content byte array
/// </summary>
/// <param name="content">Content byte array</param>
/// <returns>MD5 checksum</returns>
public static String GetMD5ForBytes(byte[] content)
{
if (content != null)
{
System.Security.Cryptography.MD5 md5Object = System.Security.Cryptography.MD5.Create();
return System.BitConverter.ToString(md5Object.ComputeHash(content)).Replace("-", "");
}
return null;
}
}
GetByNameAndVersion
public static DataPacket GetByNameAndVersion(string name, string version, TestDBContext testDBContext)
{
IQueryable<DataPacket> query = testDBContext.Set<DataPacket>();
query = query.Where(t => t.Name == name).Where(t => t.Version == version);
return query.Single();
}
Hinweis! Ich verwende eine lokale Datenbank.
Ich denke nichts falsch mit EF, höchstwahrscheinlich irgendwo in Ihrer 'DataPacketService.GetByNameAndVersion' Implementierung, zum Beispiel MD5 neu berechnet anstatt aus db etc zu lesen, oder zum Beispiel Ihre Tests haben einige Probleme mit Transaktionen etc - schwer zu sage ohne ganzes Bild. – Lanorkin
Müssen uns GetByNameAndVersion Code tatsächlich zeigen. – Evk
Danke, ich habe die Frage aktualisiert =) – kungcc