Frage

Ich verwende Linq für MySql (mit DbLinq) in einer ASP.NET MVC-Website, um SQL. Ich habe ein seltsames Caching Problem. Betrachten Sie die folgenden Methoden in meiner Repository-Klasse:

public IEnumerable<Message> GetInbox(int userId)
{
  using(MyDataContext repo = new MyDataContext(new MySqlConnection("[Connectionstring]")))
  {
    return repo.Messages.Where(m => m.MessageTo == userId);
  }
}

public IEnumerable<Message> GetOutbox(int userId)
{
  using (MyDataContext repo = new MyDataContext(new MySqlConnection("[Connectionstring]")))
  {
    return repo.Messages.Where(m => m.MessageFrom == userId);
  }
}

‚MyDataContext‘ ist die von DbLinq erzeugte Abbildung zu meiner Datenbank, die von Datacontext erbt. Ich bin nicht die Datacontext hier Wiederverwendung (der obige Code sieht ein bisschen albern, aber ich wollte unbedingt sicherstellen, dass es nicht einige Datacontext / MySqlConnection Wiederverwendung Ausgabe).

Was passiert, ist, je nachdem, welche der beiden Methoden, die ich nennen, mit dem, was userId, die Ergebnisse die gleichen bleiben. Zeitraum. Obwohl ich, dass repo.Messages hat mehr als 10 Ergebnisse sehen kann, mit MessageFrom und MessageTo Werten variieren, erhalte ich nur die ersten abgefragten Ergebnisse zurück. Also, wenn ich GetInbox(4374) nennen es gibt mir die Nachricht A und B. Meldung aufrufen GetInbox(526) danach noch gibt mir die Nachricht A und B, auch wenn es sind Nachrichten C und D, die Sie haben ein userId von 526. ich habe die Anwendung neu starten alle Änderungen zu sehen.

Was ist denn hier los? Ich bin sicher, ich tue etwas so dumm, dass ich mich schämen sein werde, wenn es mir jemand hinweist. Wenn ich nicht etwas sehr dumm tun, dann finde ich dieses Problem sehr seltsam. Ich habe gelesen, nicht die Wiederverwendung von Datacontext, aber ich bin es nicht. Warum dieses Caching-Problem? Unten ist mein Controller-Code, aber ich bezweifle es wichtig ist:

[Authorize]
public ActionResult Inbox(int userId)
{
  Mailbox inbox = new Mailbox(userId, this.messageRepository.GetInbox(userId));
  return PartialView("Inbox", inbox);
}

Zwar gibt es ähnliche Fragen auf SO, ich habe nicht eine Antwort auf diese genaue Frage gefunden. Vielen Dank!

UPDATE : Änderung des Codes zu: return repo.Messages.ToList().Where(m => m.MessageFrom == userId); behebt es, funktioniert es dann in Ordnung. Es scheint wie ein Cache-Problem. Allerdings habe ich natürlich nicht will, es auf diese Weise zu beheben. Ändern Sie den Code so, dass die Datacontext nach der Abfrage nicht angeordnet ist, tut nicht , um das Problem zu beheben.

War es hilfreich?

Lösung 4

Nun, es schien, dass es ein Problem mit DbLinq ist. Ich benutzen Quellcode von 3 Wochen alt und es gab einen apparant Fehler in Querycache (obwohl es hat immer da drin). Es gibt einen kompletten Thread, der diese hier .

ich die DbLinq Quelle aktualisiert. Querycache wird deaktiviert nun (nicht Performance-Einbußen bedeuten) und auch zumindest jetzt funktioniert es. Ich muss sehen, ob die Leistung akzeptabel ist. Muss zugeben, dass ich ein wenig verwirrt bin zwar als das, was ich versuche, ein gemeinsames linq2sql Muster zu tun ist. Vielen Dank an Alle.

Andere Tipps

Ich schrieb ein paar ziemlich ähnlich Code, der gut zu funktionieren scheint. Der einzige Unterschied besteht darin, dass, wie Marc sagt, ich bin in der Verbindungszeichenfolge vorbei und ToList auf dem Wo-Methode aufrufen. Meine Datenbank wird nicht automatisch generiert, sondern leitet sich von Datacontext. Der Code ist unten.

class Program
{
    static void Main(string[] args)
    {
        List<Item> first = GetItems("F891778E-9C87-4620-8AC6-737F6482CECB").ToList();
        List<Item> second = GetItems("7CA18DD1-E23B-41AA-871B-8DEF6228F96C").ToList();
        Console.WriteLine(first.Count);
        Console.WriteLine(second.Count);
        Console.Read();
    }

    static IEnumerable<Item> GetItems(string vendorId)
    {
        using (Database repo = new Database(@"connection_string_here"))
        {
            return repo.GetTable<Item>().Where(i => i.VendorId.ToString() == vendorId).ToList(); ;
        }
    }
}

Beginn des durch einen Test zu schreiben. Dies wird Ihnen sagen, ob Linq2Sql richtig verhält. So etwas wie:

var inboxMessages = this.messageRepository.GetInbox(userId1);
Assert.That(inboxMessages.All(m => m.MessageTo == userId1);

inboxMessages = this.messageRepository.GetInbox(userid2);
Assert.That(inboxMessages.All(m => m.MessageTo = userid2);

Wenn das erfolgreich ist, sollten Sie wirklich überprüfen, ob es die verzögerte Ausführung ist, die Probleme verursachen wird. Sie sollten inboxMessages aufzählen sofort.

Eine andere Sache, die Probleme verursachen könnte, ist die Tatsache, dass Sie Aufzählen beginnen, wenn der Datacontext bereits angeordnet ist. Der einzige Weg, dies zu lösen, ist es nicht zu entsorgen überhaupt (und auf der GC verlassen es Reinigung, wenn es den Bereich verlässt), oder kommen mit einem benutzerdefinierten IDisposable Objekt, so dass Sie ein mit drum herum setzen. So etwas wie:

using(var inboxMessages = this.messageRepository.GetInbox(userId1))
{
    Assert.That(inboxMessages.All(m => m.MessageTo == userId1);
}

Caching in LINQ-to-SQL mit dem DataContext verbunden sind, und ist vor allem auf die Identität Caching begrenzt - in den meisten Fällen wird es eine Abfrage, auch wenn Sie es erneut ausführen vorher getan haben. Es gibt ein paar Beispiele, wie .Single(x=>x.Id == id) (das hat eine besondere Behandlung).

Da Sie eindeutig einen neuer Daten-Kontext jedes Mal bekommen, ich glaube nicht, dass der Täter ist. Aber ich bin auch ein wenig überrascht, dass der Code funktioniert ... sind Sie sicher, dass repräsentativ ist?

LINQ Where Methode wird verschoben - was bedeutet, es wird nicht ausgeführt, bis Sie die Daten (zum Beispiel mit foreach) iterieren. Aber bis zu diesem Zeitpunkt haben Sie bereits angeordnet, um den Daten-Kontext! Haben Sie etwas aus dem Beispiel snipped?

Auch - durch eine SqlConnection geben (die Sie nicht dann tun Dispose()), können Sie die Bereinigung Auswirkungen sein -. Kann es bevorzugt sein, nur ihm zu geben (der Daten-Kontext) die Verbindungszeichenfolge

ich vermeiden würde DbLinq für die Produktion Code ... viele von Linq-To-SQL-Funktionen nicht implementiert sind, und durch den Quellcode zu Fuß zeigt eine zureichende Reife ... sind viele der Verfahren nicht umgesetzt oder markiert als „ungekündigten“.

... Sie sind gewarnt worden!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top