Zur Zeit wird gefiltert nach: fehler
Filter zurücksetzen

Entity Framework 4 - Der Designer stottert bei zusammengesetzten Schlüsseln (CompositeKey)

Heute wurde ich mit einem interessanten Problem im Entity Designer bei zusammengesetzten Schlüsseln konfrontiert. Das Modell wurde mit dem Assistenten angelegt. Dabei war die Einstellungen "Fremdschlüsselspalten in das Modell einbeziehen" aktiviert und es wurde die Standard-Code Generierungsvorlage verwendet.

Das Modell hatte in etwa folgenden Aufbau:

Abbildung 1
Abbildung 1 Teilmodell im Entity Framework mit Composite Key

Der erste Test, der sich mit dem Einfügen von Daten in die Datenbank befasste, scheiterte und lieferte folgendes Resultat:

Abbildung 2
Abbildung 2 Insert-Test schlägt fehl, bei Entitäten mit Composite Key

Die passende Fehlermeldung dazu lautet:

Die Personen.Test.CommentTest.Comment_Insert_Test-Testmethode hat eine Ausnahme ausgelöst: System.Data.UpdateException: EntitySet 'Comment' kann nicht aktualisiert werden, denn es hat eine DefiningQuery, und im <ModificationFunctionMapping>-Element ist kein <InsertFunction>-Element zur Unterstützung des aktuellen Vorgangs vorhanden.

Im ersten Moment beginnt das überlegen, DefiningQuery? Warum legt der Designer ein DefiningQuery für diese Tabelle an? In diesem Fall kann der Insert-Mechanismus gar nicht funktionieren, weil keine Prozeduren vorhanden sind. Ein Blick in das XML (Öffnen mit XML Text Editor) bestätigt auch die Fehlermeldung:


    <edmx:StorageModels>
      <Schema Namespace="Model.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
        <EntityContainer Name="ModelStoreContainer">
          <EntitySet Name="Comment" EntityType="Model.Store.Comment" store:Type="Tables" store:Schema="dbo" store:Name="Comment">
            <DefiningQuery>SELECT 
      [Comment].[PersonID] AS [PersonID], 
      [Comment].[CommentTypeID] AS [CommentTypeID], 
      [Comment].[Note] AS [CO_Note]
      FROM [dbo].[Comment] AS [Comment]</DefiningQuery>
          </EntitySet>

Prozeduren will ich für dieses Szenario auf keinen Fall generieren, also bleibt mir nichts anderes übrig, als das XML anzupassen. Dazu gehe ich folgendermassen vor:

  1. DefinigQuery-Tag mit Inhalt entfernen
  2. store:Name=“Comment“ entfernen
  3. store:Schema=“dbo“ ändern in Schema=“dbo“
  4. XML-Datei speichern

Ist das Ganze angepasst, bleibt folgendes XML übrig:

    
              <EntitySet Name="Comment" EntityType="Model.Store.Comment" store:Type="Tables" Schema="dbo" >
              </EntitySet>
    
    

    Zur Sicherheit wird das File im Designer geöffnet und validiert. Nach dieser Anpassung wird der Test erneut ausgeführt und der Einfüge-Test läuft nun fehlerfrei.

    Abbildung 3
    Abbildung 3 Test nach Anpassung der XML-Datei

    Daraus lässt sich schliessen, dass auch im Entity Framework 4 ein wenig Basiswissen zum Aufbau der XML-Datei nicht schaden kann. Den Nachteil dieser Variante will ich auch nicht vorenthalten. Mit jeder Modell-Anpassung müssen diese Schritte wiederholt werden.

    Dieses Problem kann bei der codezentrierten Anwendungsentwicklung mit dem DbContext sicherlich auch entstehen, da der DbContext das XML zur Laufzeit erstellt. Dann besteht nicht die einfache Möglichkeit, dass XML anzupassen. Wer mit anderen Datenbanken wie zum Beispiel MySQL im codezentrierten Ansatz gearbeitet hat, kennt sicherlich die Probleme jenseits des dbo-Schemas. ;-)

    Zurück

    27.01.2011
    22:11

    Lesson learnt: Oracle mag ich nicht

    Wer kennt das Sprichwort nicht: Lächle und sei froh, es könnte schlimmer kommen, ich lächelte und war froh und es kam schlimmer.

    Vor allem ist es immer wieder interessant, dass man Dinge erleben kann, die sich wie eine unglaubliche Geschichte anhören. In einem der letzten Projekte ging es mir so.

    Das Hauptproblem in einem Projekt war, dass ein DWH, dass auf einer eingerichteten Oracle-Schreibmaschine, die nicht den Anspruch einer soliden Grundlage erfüllte, problemlos lief. Auf dem Zielsystem unterlag die Performance jedoch starken Schwankungen. Einen Hinweis zur Definition Schreibmaschine: So nenne ich Rechner, die eigentlich nur für Office vorgesehen sind und unter dem Windows-Leistungsindex von 4 liegen.

    Nach dem ersten Review kam u. a. heraus, dass die Umgebung virtualisiert war und es mehrere Zonen gab. Was für mich die Performanceschwankungen erklärte, stellte aber für den Performance-Spezialist (Guru) nicht das Problem dar und er präsentierte auch ein paar angepasste SQL-Skripts. Um dies auch rechtfertigen zu können, wurden kurzerhand die spezifizierten Hardwareanforderungen auf die tatsächliche Umgebung angepasst. Das ist mal agiles Projektmanagement aus einem anderen Blickwinkel. Für mich kam dadurch eine neue Herausforderung hinzu: Wie mache ich aus einer Schreibmaschine einen Taschenrechner? Der RAM ist ja schnell begrenzt, aber die CPU-Leistung? So bin ich auch mit cpulimit in Berührung gekommen.

    Für mich war das eine sehr wichtige Erfahrung, denn so konnte ich auch lernen, dass Gutes SQL in Oracle-Umgebungen gleichzusetzen ist mit produktspezifisch und Tricky. Ein weiterer Vorteil, die Empfehlungen aus den Review habe ich in einer Testumgebung auf einem SQL-Server testen können.

    Nach diesen ersten Tests habe ich doch mal im Duden zur Bedeutung von Oracle nachschlagen müssen und da steht Folgendes:

    Ora|kel das; -s, - <lat.; »Sprechstätte«>:

    a) Stätte (bes. im Griechenland der Antike), wo Priester[innen], Seher[innen] o. Ä. Weissagungen verkündeten oder [rätselhafte, mehrdeutige] Aussagen in Bezug auf gebotene Handlungen, rechtliche Entscheidungen o. Ä. machten;

    b) durch das Orakel (a) erhaltene Weissagung, [rätselhafte, mehrdeutige] Aussage Duden - Das Fremdwörterbuch, 9. Aufl. Mannheim 2007 [CD-ROM]

    Rätselhafte, mehrdeutige Aussage da habe ich doch ein Déjà-vu. Denn im ersten Review wurde bspw. ein Punkt kritisiert, welcher im zweiten wieder empfohlen wurde. Auch gab es Kritikpunkte an ein paar Einstellungen, die wir auf Empfehlung des Oracle-DBA implementierten. Die Literatur, die ich mir zum Thema organisierte, war für den Guru natürlich nicht die beste und er musste den Autor Donald K. Burleson eines Werkes auch kritisieren. Das hat System, denn in Oracle-Umgebungen macht man gerne den Developer zum Sündenbock.

    Ganz ehrlich besser hätte Oracle seinen Namen gar nicht treffen können, bildlich stelle ich mir das so vor:.

    Abbildung 1
    Abbildung 1 Oracle-Consulting, demnächst bei Mike Shiva?

    Auch wenn Oracle einen grösseren Funktionsumfang bietet, so sind damit Sachen möglich, die man besser nicht machen sollte, da sie zu Performanceeinbussen führen.

    Was sich aus den Tests auf dem SQL Server ableiten lässt, ist Folgendes:

    • Ein Oracle-Developer der SQL für den SQL-Server schreiben soll, wird keine Probleme bekommen, da dieser sehr tolerant und robust ist.
    • Ein SQL-Server-Developer sollte vorher die Tipps und Tricks-Kurse der Gurus besuchen. Da diese auch Geld verdienen wollen, werden sicherlich nicht alle Tricks im ersten Kurs verraten. Mit dieser Salami-Taktik lässt sich gut verdienen und mit ein bisschen Geschick nimmt der Guru den eigentlichen Kunden auch gleich mit. Um dies zu umgehen, sollten die Schulungen nicht bei „Wir machen alles Unternehmen“ gebucht werden, die einen noch die Unterstützung anbieten. ;-)
    • Während man in der Oracle-Umgebung mit dem Feintuning beschäftigt ist und womöglich noch auf das schlechte SQL der Developer schimpft, weil mal wieder der Append-Hint bei grossen Datenmengen fehlt, lassen sich mit dem SQL-Server schon die ersten Kundenanforderungen realisieren. ;-)
    • Der mit Oracle mitgelieferte SQL Developer ist ein schlechter Aprilscherz.
    • Dem Oracle-Developer und Guru muss man vorher vielleicht noch das Lizenzmodell erklären, sonst könnte es passieren, dass er viele Funktionalitäten der Tools nicht nutzt, in der Annahme diese seien nicht lizenziert.

    So etwas passiert eben, wenn die Erwartungen zu hoch sind und deswegen habe ich jetzt um so mehr Freude daran, einen Oracle-Server in die ewigen Jagdgründe migrieren zu dürfen, so als Wiedergutmachung.

    Zurück

    16.07.2010
    00:25

    Parametrisierte Text Templates und System.Runtime.Serialization.SerializationException

    Zurzeit beschäftige ich mich mit den T4 Templates. Ein sporadisches Problem ala Murphy trat bei parametrisierten Vorlagen auf. Wenn ich diese innerhalb einer anderen Textvorlage aufgerufen habe und einen Parameter mit einem benutzerdefinierten Objekt übergeben wollte begrüsste mich die Fehlermeldung:

    Auszug Fehlermeldung
    Error        Running transformation:
    System.Runtime.Serialization.SerializationException: Unable to find
    assembly 'UmlHelper, Version=1.0.0.0, Culture=neutral,
    PublicKeyToken=null'.
    
    Server stack trace:
       at
    System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
       at
    System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo
    assemblyInfo, String name)
       at
    System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String
    objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA,
    Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader
    objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo,
    SizedArray assemIdToAssemblyTable)
       at
    System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped
    record)
       at
    System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum
    binaryHeaderEnum)
       at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
       at
    System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler
    handler, __BinaryParser serParser, Boolean fCheck, Boolean
    isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at
    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
    serializationStream, HeaderHandler handler, Boolean fCheck, Boolean
    isCrossAppDomain, IMethodCallMessage methodCallMessage)
       at
    System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream
    stm)
       at
    System.Runtime.Remoting.Messaging.SmuggledMethodCallMessage.FixupForNewAppDomain()
       at
    System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[]
    reqStmBuff, SmuggledMethodCallMessage smuggledMcm,
    SmuggledMethodReturnMessage& smuggledMrm)
       at
    System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(Object[]
    args)
    
    Exception rethrown at [0]:
       at
    System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage
    reqMsg, IMessage retMsg)
       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
    msgData, Int32 type)
       at
    Microsoft.VisualStudio.TextTemplating.ITextTemplatingSessionHost.set_Session(ITextTemplatingSession
    value)
       at
    Microsoft.VisualStudio.TextTemplatingBD1EC50CBA912372FF5EDDFDC3DFE64D.GeneratedTextTransformation.GetGeneratedOutputWithTemplate(String
    templateName, ObjectData element)
       at
    Microsoft.VisualStudio.TextTemplatingBD1EC50CBA912372FF5EDDFDC3DFE64D.GeneratedTextTransformation.TransformText()
       at
    Microsoft.VisualStudio.TextTemplating.TransformationRunner.RunTransformation(TemplateProcessingSession
    session, String source, ITextTemplatingEngineHost host, String&
    result)
    
    

    Der Aufruf der Parameter-Vorlage erfolgte in der Hauptvorlage nach folgenden Muster:

    C# Class Feature Block 
    private string GetGeneratedOutputWithTemplate(string templateName, TestUML.ObjectData element) 
    {		
      string templateFile = this.Host.ResolvePath(templateName);
      string templateContent = File.ReadAllText(templateFile);
    
      TextTemplatingSession session = new TextTemplatingSession();
      session["Element"] = element;
    
      // requires host specific true
      var sessionHost = (ITextTemplatingSessionHost) this.Host;
      sessionHost.Session = session;
    
      Engine engine = new Engine();
      string generatedContent = engine.ProcessTemplate(templateContent, this.Host);
    
      return generatedContent;
    } 
    
    

    In der Session wurde ein Objekt übergeben, das in der aktuellen Vorlage erstellt wurde. Im Template mit dem Parameter soll dann nur noch die Ausgabe aufbereitet werden.

    Die parametrisierte Vorlage ist so weniger komplex und enthält nur die Ausgabelogik:

    Parametrisierte T4 Vorlage 
    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ parameter name="Element" type="TestUML.ObjectData" #>
    /// 
    namespace <#= Element.Namespace #>
    {
      using System;
    	
      public partial class <#=  Element.ObjectName #>
      {
    <# 
         foreach (var item in Element.ObjectAttributes) {
    #>	
          public <#= item.TypeName #> <#= item.Name #> { get; set; }
    <# 
          }
    #>
          }
    }
    
    

    Wie kam nun dieser Fehler zustande und warum? Der Code wird innerhalb einer AppDomain ausgeführt. So war es sporadisch möglich, dass das Helper-Objekt nicht gefunden werden konnte, da die Templates bzw. die Dll-Datei nicht innerhalb der gleichen AppDomain liefen. Lösen konnte ich das Problem, indem ich der Hilfsklasse die Parent-Klasse MarshalByRefObject spendierte. Diese ermöglicht den Zugriff auf das Objekt über die AppDomain-Grenzen hinaus.

    C# (Hilfsobjekt)
    [Serializable]
    public class ObjectData : MarshalByRefObject
    {
        public string Namespace { get; set; }
        public string ObjectName { get; set; }
        public List ObjectAttributes { get; set; }
    }
    
    
    

    Mal sehen, ob die sporadische Fehlermeldung nun auch definitiv beseitigt ist.

    Zurück

    Translate this page

    Kategorien

    • [-].NET Development (215)
    • [-]Datenbank (26)
    • HTML (1)
    • Konfiguration (12)
    • Mind Map (10)
    • Off-topic (9)
    • Open Source (3)
    • Qualität (7)
    • Sharepoint (6)
    • Sicherheit (2)

    Archiv

    Social Bookmarking

    Bookmark bei: Mr. Wong Bookmark bei: Webnews Bookmark bei: Icio Bookmark bei: Oneview Bookmark bei: Linkarena Bookmark bei: Favoriten Bookmark bei: Seekxl Bookmark bei: Favit Bookmark bei: Social Bookmarking Tool Bookmark bei: Power Oldie Bookmark bei: Bookmarks.cc Bookmark bei: Newskick Bookmark bei: Newsider Bookmark bei: Linksilo Bookmark bei: Readster Bookmark bei: Folkd Bookmark bei: Yigg Bookmark bei: Digg Bookmark bei: Del.icio.us Bookmark bei: Reddit Bookmark bei: Simpy Bookmark bei: StumbleUpon Bookmark bei: Slashdot Bookmark bei: Netscape Bookmark bei: Furl Bookmark bei: Yahoo Bookmark bei: Spurl Bookmark bei: Google Bookmark bei: Blinklist Bookmark bei: Blogmarks Bookmark bei: Diigo Bookmark bei: Technorati Bookmark bei: Newsvine Bookmark bei: Blinkbits Bookmark bei: Ma.Gnolia Bookmark bei: Smarking Bookmark bei: Netvouz Information