Mittwoch, 31. März 2010

Nachträglich OnDelete: Cascade im EF-Modell ?

Ich hatte gerade auf einer bestehenden DB-Relation die "on update: Cascade" gesetzt, und daraufhin mein EF-Modell ge-updated.
Ein Blick in das edmx zeigte auch den erwarteten Eintrag im SSDL:

<Association Name="FK_Foo_Bar">
  <End Role="Bar" Type="FooBarModel.Store.Bar" Multiplicity="1">
 <OnDelete Action="Cascade" />
  </End>
  <End Role="Foo" Type="FooBarModel.Store.Foo" Multiplicity="*" />
  <ReferentialConstraint>
 <Principal Role="Bar">
   <PropertyRef Name="ID" />
 </Principal>
 <Dependent Role="Foo">
   <PropertyRef Name="BarId" />
 </Dependent>
  </ReferentialConstraint>
</Association>

Leider stellte sich die Gewünschte Funktionalität nicht ein: "A relationship is being added or deleted from an AssociationSet 'FK_foo_bar'. With cardinality constraints, a corresponding 'bar' must also be added or deleted."
Nach reichlich Ärger und ein wenig googeln war der Fehler schnell gefunden: das CSDL wird nicht automatisch mit angepasst.

Nachdem also im CSDL-Teil der edmx folgendes manuell ergänzt wurde:

<Association Name="FK_Foo_Bar">
  <End Role="Bar" Type="FooBarModel.Bar" Multiplicity="1">
 <OnDelete Action="Cascade" />
  </End>
  <End Role="Foo" Type="FooBarModel.Foo" Multiplicity="*" />
</Association>

Funktioniert auch das Löschen mit onDelete:cscade
Bleibt nur zu hoffen, dass sich die update-Funktionen des Designers im EF4 deutlich verbessert...

Montag, 22. März 2010

Geekfaktor…

Bei Julie Lerman habe ich gerade gelesen, dass man seinen Geekfaktor messen lassen kann – das musste ich natürlich ausprobieren:

Donnerstag, 11. März 2010

Neo-Layout und Geschwindigkeit zum Zweiten.

Über das neo-Layout hatte ich ja bereits berichtet.
Ich bin mit meiner Geschwindigkeit immer noch nicht viel weiter...
26 Wörter
Aber dafür mit meiner Tastatur:

Problematisch ist an dem Ganzen, dass ich beim Arbeiten nicht "einfach" auf neo umstellen kann. (Man stelle sich einen Mitarbeiter vor, der nichts ahnend an meinen Rechner geht und etwas tippen will...)
Somit arbeite ich die meiste Zeit des Tages mit QWERTZ, bei längeren Texten schalte ich "heimlich" auf neo um (NeoVars sei Dank)...

Montag, 9. November 2009

NUnit im STA - Modus

Neulich hatte ich die Anforderung, dass ein Programm Daten der Zwischenablage nutzen und modifizieren sollte. Ich habe (natürlich) angefangen einen Test zu schreiben. Leider war dies mit dem Unit-Test-Tool meiner Wahl (NUnit) nicht möglich. Der Fehler:
System.Threading.ThreadStateException: Der aktuelle Thread muss in den STA-Modus (Singlethreadapartment) gesetzt werden, bevor OLE-Aufrufe durchgeführt werden können.
Der Fehler tritt im Übrigen auch auf, wenn man versucht UserControls zu testen und sollte für WPF und WinForms gleich sein.
Die Lösung des Problems: NUnit-Tests im Single-Threaded Apartment (STA) statt in der Vorgabe (Multithreaded Apartment (MTA)) laufen lassen. Das Vorgehen: Man erstellt eine einfache app.config mit folgendem Inhalt:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="NUnit">
            <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
        </sectionGroup>
    </configSections>
    <NUnit>
        <TestRunner>
            <!-- Valid values are STA,MTA. Others ignored. -->
            <add key="ApartmentState" value="STA" />
            <!-- See ThreadPriority enum for other valid values -->
            <add key="ThreadPriority" value="Normal" />
        </TestRunner>
    </NUnit>
</configuration>
Damit läuft NUnit im STA, und die es kann auf die Zwischenablage zugegriffen werden.
Die Lösung habe ich von hier.

Dienstag, 3. November 2009

ReportPropertyChanged vs. OnPropertyChanged in Entities

Gerade etwas länger mit folgender Fehlermeldung gerungen: System.ArgumentException: Die Eigenschaft 'Foo' weist keine gültige Entitätszuordnung für das Entitätsobjekt auf. Weitere Informationen finden Sie in der Dokumentation zu Entity Framework.
Der Fehler trat immer auf,  wenn ich Foo einen wert zuweisen wollte.

Ursache des Fehlers war, das ich meinem eigenen Post über Zusammengesetzte Properties nicht gefolgt war, sondern statt dessen auf diversen Settern noch ReportPropertyChanged("Foo") programmiert hatte.
ReportPropertyChanged ist abernicht das gleiche wie OnPropertyChanged. ReportPropertyChanged scheint noch mehr zu tun und funktioniert daher nur auf Properties aus Enities mit Entitätszuordnung.
Nachdem ich den Fehler gefunden hatte machte die Fehlermeldung auf einmal auch viel mehr sinn.
Die Lösung des Problems war also einfach nicht ReportPropertyChanged zu benutzen, sondern OnPropertyChanged.
(Und bei dieser gelegenheit noch einmal mein Vorgehen in diesem Fall zu überdenken, und mich etwas mehr an meine eigenen Posts halten.)

Sonntag, 25. Oktober 2009

BeforeSaveEvent in EntityFramework

Neulich habe ich nach so etwas wie BeforeSave gesucht für meine Entities. Folgendes war meine Lösung (In einer partial class):
public partial class MyEntities
{
    partial void OnContextCreated()
    {
        this.SavingChanges += HandleSavingChanges;
    }

    private static void HandleSavingChanges(object sender, EventArgs e)
    {
        MyEntities context = (MyEntities) sender;
        //code....
    }
}
In meiner partial-Klasse kann ich keinen Konstruktor erstellen. (Jedenfalls keinen, der schon an anderer Stelle definiert wurde...) Daher verwende ich OnContextCreated. Dies ist eine Methode, die vom erzeugten Code ausgeführt wird. Hier hänge ich einfach einen Eventhandler an SavingChanges.

Freitag, 2. Oktober 2009

"Zusammengesetzte" Properties in EntityFramework

Ich habe für EF-Objekte gerne mal "eigene" Properties in partial classes. Diese sind dann immer vonmindestens einer, gerne auch mehreren Properties der Entity abhängig.
Damit dann auch die richtigen PropertyChanged & -Changing Events erzeugt werden habe ich gerade folgendes gefunden: Alle Properties der EF-entities implementieren eine partial OnFooChanging bzw. OnFooChanged Methode, an die man sich in der partial class einfach "anhängen" kann. Etwa so:
public string MyTitle
{
   get
   {
      return this.Title;
   }
   set
   {
      this.Title = value;
   }
}

partial void OnTitleChanging(string unused)
{
   OnPropertyChanging("MyTitle");
}

partial void OnTitleChanged()
{
   OnPropertyChanged("MyTitle");
}
BTW: "Navigierbare Properties" (damit meine ich Properties in EF-Objekten, die auf andere EF-Objekte verweisen) lösen keinen PropertiyChanged Events aus. Hier findet sich ein kleiner Workaround dazu.