2015-09-25 6 views
5

In meiner Datenbank ASP.NET MVC 4/EF 5-Webanwendung habe ich eine Tabelle mit einer Kommentarspalte, die ich neue Kommentare erstellen möchte. In der traditionellen T-SQL, schreibe ich würde: Wie veranlasse ich EF, Update SQL mit String Concat zu erstellen?

UPDATE MyTable SET Comments = 'Hi' + CHAR(13)+CHAR(10) + Comments WHERE ID = 2 

ich mit der Methode Linq finden für EF (UOW + Repository-Muster - was ich bedauere), habe ich den aktuellen Wert der Kommentare und prepend Abfrage zuerst meine neuen Kommentare dazu:

Gibt es eine Möglichkeit, dieses Update zu schreiben, ohne die DB abfragen zu müssen? Ich möchte EF irgendwie dazu bringen, das obige t-sql zu generieren. Die Kommentare können langwierig sein und mir ist es egal, was es enthält. Leistung ist ein Anliegen.

Vielen Dank im Voraus.

+1

ich hinzufügen, das hier als Kommentar, denn es ist keine Antwort: Sie haben Recht zu wissen, was EF tun kann und wie man TU es. Wenn Sie jedoch etwas tun müssen, das von EF nicht unterstützt wird, müssen Sie keine Energie verschwenden, um dies zu erreichen. Sie können einfach eine benutzerdefinierte Abfrage oder eine gespeicherte Prozedur ausführen, um Ihr Problem zu lösen. Es kann weniger schlau aussehen, aber ich glaube nicht, dass es so ist. Es gibt viele Dinge, die EF nicht tun kann, aber * du darfst * Dinge auf andere Weise tun, anstatt zu versuchen, magische oder hacky Lösungen für dein Problem zu implementieren. Dasselbe Problem tritt bei Massenaktualisierungen oder -löschungen auf. Die Lösung ist einfach – JotaBe

+0

Danke für das sagen @JotaBe - Ich habe versucht, innerhalb der Linien zu bleiben, aber manchmal ist das nicht die beste Lösung. – LoJo

+0

@LoJo du sagtest *** Ich möchte EF irgendwie dazu bringen, das t-sql oben zu erzeugen *** - deshalb wurde deine Frage auf *** 5 *** gepackt (zu der Zeit, als ich das geschrieben habe). Ansonsten ist es nur eine normale Anforderung, nichts Besonderes und sogar keine Antwort muss hinzugefügt werden. Du hättest das mit einem Kommentar verstehen sollen und die Frage sofort gelöscht. – Hopeless

Antwort

0

Das Standardupdate legt das Feld fest, und ich nehme an, dass Sie diese Funktionalität beibehalten müssen, sonst können Sie vorherige Kommentare nicht bearbeiten. Das bedeutet, dass Sie einen speziellen Update-Fall haben. Ich würde ein Verfahren zum Repository für MyTable hinzufügen, dass der SQL laufen Sie wollen:

public int PrependComment(int id, String comment) 
{ 
    String sql = "UPDATE MyTable SET Comments = {0} + 
     CHAR(13)+CHAR(10) + Comments WHERE ID = {1}"; 
    return dbContext.Database.ExecuteSqlCommand(sql, comment, id); 
} 
+0

Danke dafür.Ich habe es aus den Augen verloren, Dinge direkt zu tun. – LoJo

0

Ich denke, das einzige, was Sie spielen können, ist mit einem . Sie können jeden nicht von einer Abfrage ausgeführten Befehl abfangen (aktualisieren, löschen, einfügen) und den Befehlstext ändern, bevor er tatsächlich ausgeführt wird. Der Code hier ist nur für das Verständnis, wie es gemacht werden könnte. Sie können es für bequeme Nutzung Refactoring:

public class PrependTextInterceptor : DbCommandInterceptor 
{   
    const string table = "MyTable"; 
    const string column = "Comments"; 
    public override void NonQueryExecuting(DbCommand command, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext<int> interceptionContext) 
    { 
     command.CommandText = Regex.Replace(command.CommandText, 
           string.Format(@"(?i:(?<=^UPDATE \[.+\]\.\[{0}\]\r\nSET .* \[{1}\] =).+?(?=(,|\r\n)))", table, column), "$& + " + column);    
     base.NonQueryExecuting(command, interceptionContext);    
    } 
} 

//Usage 
DbInterception.Add(new PrependTextInterceptor()); 
//after this every time you set the Comments property 
//it will be understood as prepending  
item.Comments = displayComment.Append("Hi") 
           .Append(Environment.NewLine).ToString(); 

eine nur mehr Notiz, wenn Sie Ihre item normalerweise laden, seine Comments Eigenschaft auch geladen werden soll. So verlieren Sie den Vorteil, dass Sie es nicht zuerst laden, bevor Sie es vorziehen. Ich glaube, Sie müssen verwenden Attach, in dem Sie gerade kennen müssen die ID der Lage sein, es zu aktualisieren, ohne es zu laden (wie etwa über eine Abfrage context.Set<MyTable>().Single(e => e.ID == 2) sollte Comments dann sicher geladen sein).

+0

Vielen Dank für das Posten. Ich habe mich für eine Kombination aus @JotaBe und Colin's Empfehlung entschieden, aber ich denke, andere finden es sehr hilfreich. – LoJo