ServiceStack OrmLite 同类型负载的多个引用

ServiceStack OrmLite multiple references of same type load

在我的 ServiceStack 应用程序中,我正在实现一个简单的聊天,其中 2 个用户可以进行对话。为简单起见,我刚刚创建了一个 TextMessages table,其中包含以下字段:

public class TextMessage
{
    [AutoIncrement]
    [PrimaryKey]
    public int Id { get; set; }

    [References(typeof(MyUserAuth))]
    public int FromUserId { get; set; }

    [References(typeof(MyUserAuth))]
    public int ToUserId { get; set; }

    [Reference]
    [ForeignKey(typeof(MyUserAuth))]
    public MyUserAuth FromUser { get; set; }

    [Reference]
    [ForeignKey(typeof(MyUserAuth))]
    public MyUserAuth ToUser { get; set; }

    //TimeZoneInfo.ConvertTimeToUtc(dateNow);
    public DateTime UtcReceivedOn { get; set; }

    public string Text { get; set; }
}

我的 UserAuth 继承了基础的并增加了 2 个字段:

public class MyUserAuth : UserAuth
{
    public List<TextMessage> TextMessagesAsAuthor { get; set; }

    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}

现在假设我创建了一些用户,然后创建了一些消息:

var msg1 = new TextMessage { FromUserId = 1, ToUserId = 2, UtcReceivedOn = dt, Text = "Hello" };
var msg2 = new TextMessage { FromUserId = 1, ToUserId = 3, UtcReceivedOn = dt, Text = "Hello" };
var msg3 = new TextMessage { FromUserId = 1, ToUserId = 4, UtcReceivedOn = dt, Text = "Hello" };
var msg4 = new TextMessage { FromUserId = 1, ToUserId = 4, UtcReceivedOn = dt, Text = "Hello" };

然后我尝试阅读我的用户:

var user = db.LoadSingleById<MyUserAuth>(1);

这里的问题是用户在 TextMessagesAsAuthorTextMessagesAsRecipient 中都有 4 条消息,而逻辑上 TextMessagesAsAuthor 中应该有 4 条,TextMessagesAsRecipient 中应该有 0 条。我如何告诉 OrmLite 区分这两个属性?

OrmLite 仅支持您在 TextMessage table 中使用的 multiple 1:1 Self References,它不支持您尝试的多个 1:M 外部引用声明于:

public class MyUserAuth : UserAuth
{
    public List<TextMessage> TextMessagesAsAuthor { get; set; }

    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}

Also note complex properties that don't have [Reference] attributes are blobbed with the row they're on, which isn't what you want here.

还有 OrmLite 的 POCO References only load 1-level deep,即引用不会递归地下降并加载引用的 table 引用或填充任何循环反向引用,这看起来就像您正在尝试做的那样.

所以我会按原样保留短信:

var msgs = new[]
{
    new TextMessage { FromUserId = 1, ToUserId = 2, Text = "msg #1" }, 
    new TextMessage { FromUserId = 1, ToUserId = 3, Text = "msg #2" }, 
    new TextMessage { FromUserId = 1, ToUserId = 4, Text = "msg #3" }, 
    new TextMessage { FromUserId = 1, ToUserId = 4, Text = "msg #4" }, 
};
db.InsertAll(msgs);

您可以使用它来加载他们的多个自用户引用,例如:

var msg1 = db.LoadSingleById<TextMessage>(1);
msg1.PrintDump(); //prints populated FromUser/ToUser properties

但是您无法对 MyUserAuth 多个 1:M 外部引用执行相同的操作。在这种情况下,我仍会将 TextMessage 集合添加到 MyUserAuth table,但您需要告诉 OrmLite 在创建 MyUserAuth table 时忽略它们你可以用 [Ignore] 属性来做,例如:

public class MyUserAuth : UserAuth
{
    [Ignore]
    public List<TextMessage> TextMessagesAsAuthor { get; set; }

    [Ignore]
    public List<TextMessage> TextMessagesAsRecipient { get; set; }
}

然后您可以手动填充它们,即:

var user1 = db.SingleById<MyUserAuth>(1);
user1.TextMessagesAsAuthor = db.Select<TextMessage>(x => x.FromUserId == 1);
user1.TextMessagesAsRecipient = db.Select<TextMessage>(x => x.ToUserId == 1);
user1.PrintDump(); //prints populated MyUserAuth TextMessages