繁体   English   中英

少林一对一关系

[英]One-to-one relation in Shaolinq

我正在使用Shaolinq库进行数据库使用,并且一对一关系存在问题。 我有以下数据库架构:

create table A (
    Id INT NOT NULL,
    PRIMARY KEY (`Id`)
);
create  table B (
    Id INT NOT NULL,
    PRIMARY KEY (`Id`),
    CONSTRAINT `fk_a_b_id` FOREIGN KEY (`Id`) REFERENCES `A` (`Id`)
);

基本上,这两个表包含有关相同内容的信息,只是不同的数据。 那是有人设计的方式,我无法更改。

但是,在代码中,我希望将所有这些数据放在一个对象中。 我一直在尝试BackReference,但没有运气:

[DataAccessObject]
public abstract class A : DataAccessObject<uint>
{
    [AutoIncrement]
    [PersistedMember]
    public abstract uint Id { get; set; }

    [RelatedDataAccessObjects]
    public abstract RelatedDataAccessObjects<B> Bs { get; }
}

[DataAccessObject]
public abstract class B : DataAccessObject
{
    [BackReference(Name = "", PrefixName = "", SuffixName = "")]
    public abstract A Id { get; set; }

    [PersistedMember]
    public abstract string MoreData { get; set; }
}

这创建了某种相似的模式(显然B中的Id现在不是主键),但是在我将数据填充到DB中之后,A中的Bs属性未填充引用。 简单地将类型B的抽象属性放在A中似乎也不起作用,因为同一列同时是外键和主键(Id)。

欢迎任何建议。

您是否需要从As访问B的集合? 在我看来,B是包含来自AB数据的“超类”。 如果是这样,那么您只需将A作为B的主键即可。

[DataAccessObject]
public abstract class A : DataAccessObject<uint>
{
    [PersistedMember(Name = "Id")]
    public abstract override uint Id { get; set; }

    [PersistedMember]
    public abstract string Data { get; set; }
}

[DataAccessObject]
public abstract class B : DataAccessObject<A>
{
    [PersistedMember(Name = "Id", PrefixName = "")]
    public abstract override A Id { get; set; }

    [PersistedMember]
    public abstract string MoreData { get; set; }
}

请注意,我已重写Id属性以获取与SQL匹配的列名。 默认值表示列名: AIdBId

因为主键是一个对象,所以在Shaolinq术语中将其称为“复杂主键”。 您可以使用放气的引用功能来检索对象,而只需将它们作为它们的主键即可,而无需往返数据库(更多信息: https : //github.com/tumtumtum/Shaolinq/wiki/Deflated-References

您可以查询B的特定值:

// Need to define primary key using an anonymous object because it's not an uint but rather an A that contains an uint.
model.Bs.GetByPrimaryKey(new { Id = 100 } );

您还可以使用放气的引用查询B的特定值:

model.Bs.GetByPrimaryKey(model.As.GetReference(100));

您还可以在普通的LINQ查询中使用引用:

model.Bs.Where(c => c.Id == model.As.GetReference(100) || c.Id == model.As.GetReference(101)).ToList();

您也可以直接在查询中访问嵌套/复杂的主键:

model.Bs.Where(c => c.Id.Id == 100 || c.Id.Id == 101).ToList();

请注意,由于复杂的主键被展平并存储在表B上,因此上述三个查询不需要执行隐式联接。

当你回到B ,你可以访问B.Id.Id不用往返查询,但如果你访问B.Id.Data那么这将导致B.Id到自动隐藏往返到数据库膨胀 为避免这种情况,您可以使用Include在第一个查询中自动为B.Id充气。

model.Bs.Include(c => c.Id).Single(c => c.Id == model.As.GetReference(100));

或更简洁地说:

model.Bs.Include(c => c.Id).Single(c => c.Id.Id == 100);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM