我的实体具有以下集合导航属性:
public virtual ICollection<OrderIntegrationLogEntry> LogEntries { get; set; }
而OrderIntegrationLogEntry
实体有一点点的配置:
this.HasKey(i => new {i.Id, i.IntegrationId});
this.HasRequired(i => i.Integration).WithMany(i => i.LogEntries).HasForeignKey(i => i.IntegrationId).WillCascadeOnDelete(true);
似乎这行代码:
integration.LogEntries.Add(new OrderIntegrationLogEntry
{
Id = Guid.NewGuid(),
CreatedUtc = DateTime.UtcNow,
Message = message,
Level = level,
Detail = detail
});
...导致加载集合内容的查询:
SELECT [Extent1].[Id] AS [Id], [Extent1].[IntegrationId] AS [IntegrationId],
[Extent1].[CreatedUtc] AS [CreatedUtc], [Extent1].[Level] AS [Level],
[Extent1].[Message] AS [Message], [Extent1].[Detail] AS [Detail]
FROM [dbo].[OrderIntegrationLogEntries] AS [Extent1]
WHERE [Extent1].[IntegrationId] = @EntityKeyValue1
我没想到这一点:它不应该只是添加一个吗?我需要以其他方式配置吗?
正如 Ivan 所指出的,您调用了 LogEntries getter,这会导致延迟加载。
如果不想关闭延迟加载,那么不要将日志实体添加到父级的导航属性中,只需设置新实体的 IntegrationId 和 SaveChanges()。例如
var entry = new OrderIntegrationLogEntry()
{
Id = Guid.NewGuid(),
IntegrationId = integration.Id,
CreatedUtc = DateTime.UtcNow,
Message = message,
Level = level,
Detail = detail
);
db.OrderIntegrationLogEntries.Add(entry);
db.SaveChanges();
此外,如果这是 SQL Server(也可能是其他平台),请使用顺序 GUID 生成。插入带有随机 guid 作为其前导键列的行是不必要的昂贵。对于 SQL Server,您可以在数据库中使用 NEWSEQUENTIALID() 函数作为默认值或在客户端上生成顺序 GUID
public class SQLGuidUtil
{
[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);
public static Guid NewSequentialId()
{
Guid guid;
UuidCreateSequential(out guid);
var s = guid.ToByteArray();
var t = new byte[16];
t[3] = s[0];
t[2] = s[1];
t[1] = s[2];
t[0] = s[3];
t[5] = s[4];
t[4] = s[5];
t[7] = s[6];
t[6] = s[7];
t[8] = s[8];
t[9] = s[9];
t[10] = s[10];
t[11] = s[11];
t[12] = s[12];
t[13] = s[13];
t[14] = s[14];
t[15] = s[15];
return new Guid(t);
}
}
如何在 .NET 中为 SQL Server 生成顺序 GUID
如果您希望主要在逐个集成的基础上访问日志条目,您还应该考虑翻转键列的顺序。这会将集成的日志条目存储在一起。例如
this.HasKey(i => new {i.IntegrationId, i.Id});
如果您不在 Windows 上,您可以通过从随机 GUID 开始并增加 4 个低位字节来滚动您自己的顺序 GUID 生成器。GUID 仅在 AppDomain 中是连续的,但这应该无关紧要。
像这样的东西:
namespace NewSequentialId
{
public class SQLGuidUtil
{
static object synclock = new object();
static uint seq = 0;
static byte[] seed = Guid.NewGuid().ToByteArray();
public static Guid NewSequentialId()
{
uint nextVal;
byte[] buf;
lock (synclock)
{
nextVal = seq++;
buf = (byte[])seed.Clone();
if (nextVal == 0xFFFFFFFF)
{
seed = Guid.NewGuid().ToByteArray();
seq = 0;
}
}
var seqbytes = BitConverter.GetBytes(nextVal);
if (BitConverter.IsLittleEndian)
{
buf[0] = seqbytes[3];
buf[1] = seqbytes[2];
buf[2] = seqbytes[1];
buf[3] = seqbytes[0];
}
else
{
buf[0] = seqbytes[0];
buf[1] = seqbytes[1];
buf[2] = seqbytes[2];
buf[3] = seqbytes[3];
}
return new Guid(buf);
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句