2016-05-03 13 views
2

In meiner ServiceStack App implementiere ich einen einfachen Chat, wo 2 Benutzer einen Dialog haben können. Der Einfachheit halber habe ich gerade ein Textnachrichten-Tabelle, die die folgenden Felder enthält:ServiceStack OrmLite mehrere Referenzen des gleichen Typs laden

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; } 
} 

Mein USERAUTH erbt die Basis ein und fügt 2 weitere Felder:

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

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

Lassen Sie uns jetzt sagen, dass ich einige erstellen einige Nachrichten Benutzer und dann:

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" }; 

und dann versuche ich meine Benutzer zu lesen:

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

Das Problem hier ist, dass der Benutzer 4 Nachrichten in beiden TextMessagesAsAuthor und TextMessagesAsRecipient hat, während logisch 4 in TextMessagesAsAuthor und 0 in TextMessagesAsRecipient sein sollte. Wie kann ich OrmLite mitteilen, diese beiden Eigenschaften zu unterscheiden?

Antwort

4

OrmLite unterstützt nur multiple 1:1 Self References wie Sie in Ihrem TextMessage Tabelle verwenden, ist es nicht möglich, mehrere nicht unterstützt 1: M externe Referenzen wie Sie versuchen auf erklären:

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

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

Beachten Sie auch komplexe Eigenschaften, die keine Attribute haben, sind mit der Zeile blobbed, die sie sind, was hier nicht gewünscht ist.

Auch OrmLite der POCO References only load 1-level deep, das heißt Verweise rekursiv nicht nach unten gehen und laden Sie die referenzierte Tabelle Verweise sowie oder alle zyklischen Rückverweise bevölkern das ist, was es sieht aus wie Sie zu tun versuchen.

Also würde ich die Text-Nachrichten halten, wie sie sind:

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); 

, die Sie sich mehr Selbstbenutzerreferenzen verwenden können, um zu laden, zB:

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

Aber Sie nicht in der Lage sein, Machen Sie dasselbe für MyUserAuth mehrere 1: M externe Referenzen. In diesem Fall würde ich immer noch die TextMessage Sammlungen zum MyUserAuth Tabelle hinzufügen, aber Sie werden OrmLite sagen wollen, dass sie zu ignorieren, wenn die MyUserAuth Tabelle erstellen, die Sie mit dem Attribut [Ignore] tun können, zum Beispiel:

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

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

, die Sie kann sie dann manuell auffüllen, dh:

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 
Verwandte Themen