我有 2 个域实体、成员和主题设置。一个成员可以有 0 或 1 个主题设置,我已经使用 Fluentmapping 进行了设置:
public class Member(int id, Guid externalId, string name, string email, ThemeSettings? settings) : AggregateRoot(id)
{
public Guid ExternalId { get; private set; } = externalId;
public string Name { get; private set; } = name;
public string Email { get; private set; } = email;
// Associations
public ThemeSettings? ThemeSettings { get; set; } = settings;
}
public class ThemeSettings(
int id,
int memberId,
Theme theme,
SidebarPosition sidebarPosition,
SidebarBehavior sidebarBehavior,
bool sidebarCompact) : Entity(id)
{
public int MemberId { get; private set; } = memberId;
public Theme Theme { get; set; } = theme;
public SidebarPosition SidebarPosition { get; set; } = sidebarPosition;
public SidebarBehavior SidebarBehavior { get; set; } = sidebarBehavior;
public bool SidebarCompact { get; set; } = sidebarCompact;
}
builder
.Entity<Member>()
.HasSchemaName("Member")
.HasTableName("Member")
.Property(e => e.Id).IsPrimaryKey().IsIdentity().HasColumnName("Id")
.Property(e => e.Code).IsNotNull().HasColumnName("Code")
.Property(e => e.ExternalId).IsNotNull().HasColumnName("ExternalId")
.Property(e => e.Name).IsNotNull().HasColumnName("Name")
.Property(e => e.Email).IsNotNull().HasColumnName("Email")
.Property(e => e.ThemeSettings)
.Association(e => e.ThemeSettings, e => e.Id, c => c!.MemberId, true);
builder
.Entity<ThemeSettings>()
.HasSchemaName("Member")
.HasTableName("ThemeSettings")
.Property(e => e.Id).IsPrimaryKey().IsIdentity().HasColumnName(nameof(Entity.Id))
.Property(e => e.Code).IsNotNull().HasColumnName("Code")
.Property(e => e.MemberId).HasColumnName("MemberId")
.Property(e => e.Theme).HasConversion(v => (int)v, v => (Theme)v).HasColumnName(nameof(ThemeSettings.Theme))
.Property(e => e.SidebarBehavior).HasConversion(v => (int)v, v => (SidebarBehavior)v)
.HasColumnName(nameof(ThemeSettings.SidebarBehavior))
.Property(e => e.SidebarPosition).HasConversion(v => (int)v, v => (SidebarPosition)v)
.HasColumnName(nameof(ThemeSettings.SidebarPosition))
.Property(e => e.SidebarCompact).HasColumnName(nameof(ThemeSettings.SidebarCompact));
然后我在主题设置上使用 LoadWith 查询成员。我看到查询已正确生成并返回 1 行,正如预期的那样:
DECLARE @externalId UniqueIdentifier -- Guid
SET @externalId = 'd4cee0e2-6341-43c0-93c8-f1acad44195a'
SELECT
[member_1].[Id],
[member_1].[Code],
[member_1].[ExternalId],
[member_1].[Name],
[member_1].[Email],
[a_ThemeSettings].[Id],
[a_ThemeSettings].[Code],
[a_ThemeSettings].[MemberId],
[a_ThemeSettings].[Theme],
[a_ThemeSettings].[SidebarPosition],
[a_ThemeSettings].[SidebarBehavior],
[a_ThemeSettings].[SidebarCompact]
FROM
[Member].[Member] [member_1]
LEFT JOIN [Member].[ThemeSettings] [a_ThemeSettings] ON [member_1].[Id] = [a_ThemeSettings].[MemberId]
WHERE
[member_1].[ExternalId] = @externalId
[07:41:42 Information] LinqToDB.Data.DataConnection
Query Execution Time (AfterExecute): 00:00:00.0015098
[07:41:42 Information] LinqToDB.Data.DataConnection
Total Execution Time (Completed): 00:00:00.0018493. Rows Count: 1.
它正确地为我初始化了 Member 对象,但由于某种原因,ThemeSettings 属性仍然为 null。我无法弄清楚我做错了什么,有什么想法吗?如果我在数据库上手动运行此查询,数据是正确的并且包含该成员的有效主题设置值。
数据使用存储库和规范加载,其中包含以下内容:
public async Task<IEnumerable<T>> GetBySpecificationAsync(ISpecification<T> spec)
{
var query = db.GetTable<T>().Where(spec.Criteria);
query = spec.Includes.Aggregate(query,
(current, include) => current.LoadWith(include));
return await query.ToListAsync();
}
public class MemberByExternalIdSpecification(Guid externalId)
: Specification<Domain.MemberAggregate.Member>(
member => member.ExternalId == externalId,
i => i.ThemeSettings);
规范基础初始值设定项中的第二行是在存储库中处理的包含数组。
有什么想法吗?
如果有人想知道,我忽略了 linq2db 使用主构造函数并使用参数名称来传递数据的事实。 ThemeSettings 参数的名称必须从 settings 固定为 themeSettings。
感谢 @Svyatoslav Danyliv 在 linq2db 问题部分向我指出这一点:https://github.com/linq2db/linq2db/issues/4478
public class Member(int id, Guid externalId, string name, string email, ThemeSettings? themeSettings) : AggregateRoot(id)
{
public Guid ExternalId { get; private set; } = externalId;
public string Name { get; private set; } = name;
public string Email { get; private set; } = email;
// Associations
public ThemeSettings? ThemeSettings { get; set; } = settings;
}