我必须找到两个数据集是否相同而不使用主键,只有数据。
如果存在,我必须返回主键,否则我必须插入新行并返回新主键
不是单独比较每个字段,因为我觉得这可能很慢????,我提出了这个解决方案
(我将以地址为例)
在SQL Server端,persisted
computed column
上有index
;
-- nice new function in 2012; concat
hashbytes('SHA2_256',
concat(
nchar(0x2460),[Address_Type_Id],
nchar(0x2461),[Street_Name],
nchar(0x2462),[Municipality],
nchar(0x2463),[Postal_Zip_Code],
nchar(0x2464),[Unit],
nchar(0x2465),[Street_Number],
nchar(0x2466),[PO_Box],
nchar(0x2467),[Rural_Route_Number],
nchar(0x2468),[Street_Type_Id],
nchar(0x2469),[Country_Type_Id],
nchar(0x246A),[Country_Division_Type_Id],
nchar(0x246B),[Country_Division_Other],
nchar(0x246C),[Direction_Type_Id]
)
)
在.NET端;
using(var mySHA256 = System.Security.Cryptography.SHA256Managed.Create())
{
var Value = string.Concat(
(char)0x2460, PartyAddress.AddressTypeId,
(char)0x2461, PartyAddress.StreetName,
(char)0x2462, PartyAddress.Municipality,
(char)0x2463, PartyAddress.PostalZip,
(char)0x2464, PartyAddress.Unit,
(char)0x2465, PartyAddress.StreetNumber,
(char)0x2466, PartyAddress.POBOX,
(char)0x2467, PartyAddress.RuralRouteNumber,
(char)0x2468, PartyAddress.StreetTypeId,
(char)0x2469, PartyAddress.CountryTypeId,
(char)0x246A, PartyAddress.CountryDivisionTypeId,
(char)0x246B, PartyAddress.CountryDivisionOther,
(char)0x246C, PartyAddress.DirectionTypeId);
var hashValue = mySHA256.ComputeHash(Encoding.Unicode.GetBytes(Value));
}
之后,我现在可以比较hashValue
和computed column
,它确实有效。
我的问题是,在我开始在很多其他表上实现这个之前,我应该看看另一个更好的解决方案吗?
编辑**************
添加另一个解决方案,逐字段比较,因为我使用实体框架就像这样
var addressExist = Tombstone.Addresses
.FirstOrDefault(x =>
x.Address_Type_Id == PartyAddress.AddressTypeId &&
x.Street_Name == PartyAddress.StreetName &&
x.Municipality == PartyAddress.Municipality &&
x.Postal_Zip_Code == PartyAddress.PostalZip &&
x.Unit == PartyAddress.Unit &&
x.Street_Number == PartyAddress.StreetNumber &&
x.PO_Box == PartyAddress.POBOX &&
x.Rural_Route_Number == PartyAddress.RuralRouteNumber &&
x.Street_Type_Id == PartyAddress.StreetTypeId &&
x.Country_Type_Id == PartyAddress.CountryTypeId &&
x.Country_Division_Type_Id == PartyAddress.CountryDivisionTypeId &&
x.Country_Division_Other == PartyAddress.CountryDivisionOther &&
x.Direction_Type_Id == PartyAddress.DirectionTypeId);
生成此查询
SELECT TOP (1) [Extent1].[Address_Id] AS [Address_Id]
FROM [dbo].[Address] AS [Extent1]
WHERE ([Extent1].[Address_Type_Id] = @p__linq__0) AND
(([Extent1].[Street_Name] = @p__linq__1) OR (([Extent1].[Street_Name] IS NULL) AND (@p__linq__1 IS NULL))) AND
(([Extent1].[Municipality] = @p__linq__2) OR (([Extent1].[Municipality] IS NULL) AND (@p__linq__2 IS NULL))) AND
(([Extent1].[Postal_Zip_Code] = @p__linq__3) OR (([Extent1].[Postal_Zip_Code] IS NULL) AND (@p__linq__3 IS NULL))) AND
(([Extent1].[Unit] = @p__linq__4) OR (([Extent1].[Unit] IS NULL) AND (@p__linq__4 IS NULL))) AND
(([Extent1].[Street_Number] = @p__linq__5) OR (([Extent1].[Street_Number] IS NULL) AND (@p__linq__5 IS NULL))) AND
(([Extent1].[PO_Box] = @p__linq__6) OR (([Extent1].[PO_Box] IS NULL) AND (@p__linq__6 IS NULL))) AND
(([Extent1].[Rural_Route_Number] = @p__linq__7) OR (([Extent1].[Rural_Route_Number] IS NULL) AND (@p__linq__7 IS NULL))) AND
(([Extent1].[Street_Type_Id] = @p__linq__8) OR (([Extent1].[Street_Type_Id] IS NULL) AND (@p__linq__8 IS NULL))) AND
(([Extent1].[Country_Type_Id] = @p__linq__9) OR (([Extent1].[Country_Type_Id] IS NULL) AND (@p__linq__9 IS NULL))) AND
(([Extent1].[Country_Division_Type_Id] = @p__linq__10) OR (([Extent1].[Country_Division_Type_Id] IS NULL) AND (@p__linq__10 IS NULL))) AND
(([Extent1].[Country_Division_Other] = @p__linq__11) OR (([Extent1].[Country_Division_Other] IS NULL) AND (@p__linq__11 IS NULL))) AND
(([Extent1].[Direction_Type_Id] = @p__linq__12) OR (([Extent1].[Direction_Type_Id] IS NULL) AND (@p__linq__12 IS NULL)))
答案 0 :(得分:2)
如果您认为比较每个字段的速度会很慢,请考虑您的替代解决方案:
所以你只做了2n次操作2 x(2n + 2n + hash(n))。另外,你创建了很多字符串,每个字符串都增加了CPU周期和内存(字符串在.Net中是不可变的)。
你可以清楚地看到哪一个会变慢。
更新
答案 1 :(得分:0)
如果我不必自动执行此操作(即您只是偶尔执行此操作,并且手动比较已经足够),那么我会考虑使用专门的SQL数据库比较工具。然后我将.NET DataTable
加载到临时SQL Server数据库中,将它们命名为与它们相对应的SQL Server表,并使该工具将临时DB与实际DB进行比较。
除此之外,计算每行的校验和似乎是一种明智的方法。
(替代方案:并非我发现以下想法是一种好方法,而且我从未测试过;但从理论上讲,您还可以在所有表格列中定义UNIQUE
约束,然后尝试将DataRow
的{{1}}的每个数据插入其中。如果DataTable
成功,则SQL Server表没有该记录,即您的两个表不相同。如果唯一约束使每个INSERT
失败,并且INSERT
和SQL Server表具有完全相同的行数,则它们只是相同的。)