RemovedEntitiesTracker

Posts   
 
    
Jazz
User
Posts: 63
Joined: 12-Aug-2005
# Posted on: 01-Oct-2007 21:57:57   

Hi there,

I use RemovedEntitiesTracker to keep track of removed Items. So after removing an Item from an EntityCollection the removed Item is visible in the RemovedEntitiesTracker Collection. So far so good.

For generic removal of Entities I wrote a WebService Method that deletes items from a EntityCollection. So basically what I'm doing is putting everything from the RemovedEntitiesTracker into a new EntityCollection. After that I remove every item from that collection using DataAccessAdapter.DeleteEntityCollection at the WebService.

I cannot get this to work. Everytime the Collection is being deserialized on the WebService side, I get the following Error:

[43332] Exception: System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: Die Anforderung konnte vom Server nicht gelesen werden. ---> System.InvalidOperationException: Fehler im XML-Dokument. ---> System.ArgumentNullException: Der Wert darf nicht NULL sein. 
[43332] Parametername: g 
[43332] bei System.Guid..ctor(String g) 
[43332] bei SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.Xml2Entity(XmlReader reader, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences) 
[43332] bei SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2.Xml2Entity(XmlReader reader, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences) 
[43332] bei SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.Xml2EntityCollection(XmlReader reader, Dictionary`2 processedObjectIDs, List`1 nodeEntityReferences) 
[43332] bei SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.ReadXml(XmlReader reader, XmlFormatAspect format) 
[43332] bei SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1.System.Xml.Serialization.IXmlSerializable.ReadXml(XmlReader reader) 
[43332] bei System.Xml.Serialization.XmlSerializationReader.ReadSerializable(IXmlSerializable serializable) 
[43332] bei Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReader1.Read8_DeleteEntityCollection() 
[43332] bei Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer8.Deserialize(XmlSerializationReader reader) 
[43332] bei System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) 

What I discovered, is, when I serialize an Entity from the RemovedEntitiesTracker collection it looks rather crippled. Like:

<?xml version="1.0" encoding="utf-8"?> 
<EntityCollection> 
  <EntityCollection Format="Compact25"> 
    <PrintSubstrateEntity ObjectID="e77ab2d6-c9e0-4d6b-bd9a-0960624c300b"> 
      <Id>45</Id> 
      <Token>TEST3</Token> 
      <GrammageInternal>100</GrammageInternal> 
      <GrammageExternal>150</GrammageExternal> 
      <Created>2007-09-16T20:04:24.3900000+02:00</Created> 
      <LastModified>2007-09-16T20:04:24.3900000+02:00</LastModified> 
      <Active>true</Active> 
      <ArticleTypePaperPrint>dgoPortalMapping2.HelperClasses.EntityCollection`1[dgoPortalMapping2. EntityClasses.ArticleTypePaperPrintEntity]</ArticleTypePaperPrint> 
      <Note></Note> 
      <PrintSubstrateTranslation>dgoPortalMapping2.HelperClasses.EntityCollection`1[dgoPortalMapping2. EntityClasses.PrintSubstrateTranslationEntity]</PrintSubstrateTranslation> 
      <_lps fs="IAA=" es="1" /> 
    </PrintSubstrateEntity> 
    <_lps f="7" /> 
  </EntityCollection> 
</EntityCollection>

But it should look like(?):

<?xml version="1.0" encoding="utf-8"?> 
<EntityCollection> 
  <EntityCollection Factory="dgoPortalMapping2.FactoryClasses.PrintSubstrateEntityFactory, dgoPortalMapping2" Format="Compact25"> 
    <PrintSubstrateEntity ObjectID="61b470b8-ae9d-4eb6-b767-6517b9f01d4c"> 
      <Id>41</Id> 
      <Token>AFFICH_115_BLAU</Token> 
      <GrammageInternal>115</GrammageInternal> 
      <GrammageExternal>115</GrammageExternal> 
      <Created>2006-02-07T17:42:07.5630000+01:00</Created> 
      <LastModified>2006-05-29T17:51:07.0300000+02:00</LastModified> 
      <Active>true</Active> 
      <PrintSubstrateTranslation> 
        <PrintSubstrateTranslationEntity ObjectID="0c66a7ff-6c8c-445b-93fb-f7e9c612f7b5"> 
          <IdSource>41</IdSource> 
          <LanguageToken>DE</LanguageToken> 
          <Name>Affichenpapier</Name> 
          <Description>Blaue Rückseite.</Description> 
          <PrintSubstrate Ref="61b470b8-ae9d-4eb6-b767-6517b9f01d4c" /> 
          <_lps fs="AA==" es="1" /> 
        </PrintSubstrateTranslationEntity> 
        <_lps f="7" /> 
      </PrintSubstrateTranslation> 
      <_lps fs="IAA=" es="1" /> 
    </PrintSubstrateEntity>
...

Am I on the wrong path? I mean, was it ment to be used in that way? I find the RemovedEntitiesTracker Property very helpful and it would cost me a lot of time migrating to UnitOfWork and using events like EntityRemoved or something. In another post I saw somebody else using it, but he used Remoting. Maybe the RemovedEntitiesTracker could be serialized as well so I could access the to-be-deleted-items from one EntityCollection, which also holds the modified ones, directly in the WebService.

Regards, André

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 02-Oct-2007 08:17:08   

Hi Jazz,

I think your problem is related to this: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=11076

BTW, Could you please traslate this: Die Anforderung konnte vom Server nicht gelesen ?

David Elizondo | LLBLGen Support Team
Jazz
User
Posts: 63
Joined: 12-Aug-2005
# Posted on: 02-Oct-2007 14:01:20   

Hi David,

that message just means that the WebService Method couldn't be executed. Yes I've read through the thread you are referring to and I also applied the code to the EntityCollection class, but I do believe that this works only when using Remoting which uses another Formatter imho. It is suggested to use a UnitOfWork for WebServices. Well, yes, but that means that I should be able to get the to-be-deleted Entities from the RemovedEntitiesTracker property, right? Because on the client side there is no serialization applied, which means that there is just the mechanism of putting the entity into the RemovedEntitiesTracker Collection after Remove is called from a client-based control.

What I was trying to point out, is, that Entities ending up in the RemovedEntitiesTracker are different from the Entities that were in the original collection.

Does the problem come from the complexity of my Entities? There is at least one 1:n collection involved as you can see in the above post. And those Relations look crippled after being serialized from the RemovedEntitiesTracker collection:


     <PrintSubstrateTranslation>dgoPortalMapping2.HelperClasses.EntityCollection`1[dgoPortalMapping2. EntityClasses.PrintSubstrateTranslationEntity]</PrintSubstrateTranslation> 
     <_lps fs="IAA=" es="1" /> 

and before being removed:

   <PrintSubstrateTranslation> 
        <PrintSubstrateTranslationEntity ObjectID="0c66a7ff-6c8c-445b-93fb-f7e9c612f7b5"> 
         <IdSource>41</IdSource> 
         <LanguageToken>DE</LanguageToken> 
         <Name>Affichenpapier</Name> 
         <Description>Blaue Rückseite.</Description> 
         <PrintSubstrate Ref="61b470b8-ae9d-4eb6-b767-6517b9f01d4c" /> 
         <_lps fs="AA==" es="1" /> 
        </PrintSubstrateTranslationEntity> 
        <_lps f="7" /> 
     </PrintSubstrateTranslation> 

Regards, André

Jazz
User
Posts: 63
Joined: 12-Aug-2005
# Posted on: 02-Oct-2007 14:42:06   

Something to add. I attached to the EntityRemoving event from the EntityCollection(in this case _CurrentPrintSubstrates):


void CurrentPrintSubstrates_EntityRemoving(object sender,CancelableCollectionChangedEventArgs e) {
    foreach(PrintSubstrateEntity psE in _CurrentPrintSubstrates) {
        Debug.WriteLine("Collection to remove from: " + ReflectionHelper.Serialize(psE));
    }
    Debug.WriteLine("about to remove: " + ReflectionHelper.Serialize(e.InvolvedEntity));
}

ReflectionHelper.Serialize just serializes the object using XmlFormatter. In this case everything looks pretty good. The Entities in the _CurrentPrintSubstrates collection get serialzed correctly. Also the Entity that is about to be removed is correctly serialized:


<PrintSubstrateEntity ObjectID="b6473b78-1eac-49e5-9ff3-2d8c0beb2a8c" Format="Compact25"> 
  <Id>45</Id> 
  <Token>TEST3</Token> 
  <GrammageInternal>100</GrammageInternal> 
  <GrammageExternal>150</GrammageExternal> 
  <Created>2007-09-16T20:04:24.3900000+02:00</Created> 
  <LastModified>2007-09-16T20:04:24.3900000+02:00</LastModified> 
  <Active>true</Active> 
  <PrintSubstrateTranslation> 
    <PrintSubstrateTranslationEntity ObjectID="79195c0b-38c5-4e49-844d-207d67d86885"> 
      <IdSource>45</IdSource> 
      <LanguageToken>DE</LanguageToken> 
      <Name>dfgdfg</Name> 
      <PrintSubstrate Ref="b6473b78-1eac-49e5-9ff3-2d8c0beb2a8c" /> 
      <_lps fs="gA==" es="1" /> 
    </PrintSubstrateTranslationEntity> 
    <_lps f="7" /> 
  </PrintSubstrateTranslation> 
  <_lps fs="IAA=" es="1" /> 
</PrintSubstrateEntity>

Now I attached the EntityRemoved event and did the same stuffs from above. Now the removed Entity's serialized Xml looks like:


<PrintSubstrateEntity ObjectID="b6473b78-1eac-49e5-9ff3-2d8c0beb2a8c" Format="Compact25"> 
  <Id>45</Id> 
  <Token>TEST3</Token> 
  <GrammageInternal>100</GrammageInternal> 
  <GrammageExternal>150</GrammageExternal> 
  <Created>2007-09-16T20:04:24.3900000+02:00</Created> 
  <LastModified>2007-09-16T20:04:24.3900000+02:00</LastModified> 
  <Active>true</Active> 
  <ArticleTypePaperPrint>dgoPortalMapping2.HelperClasses.EntityCollection`1[dgoPortalMapping2.EntityClasses.ArticleTypePaperPrintEntity]</ArticleTypePaperPrint> 
  <Note></Note> 
  <PrintSubstrateTranslation>dgoPortalMapping2.HelperClasses.EntityCollection`1[dgoPortalMapping2.EntityClasses.PrintSubstrateTranslationEntity]</PrintSubstrateTranslation> 
  <_lps fs="IAA=" es="1" /> 
</PrintSubstrateEntity>

What am I doing wrong? ;-)

Regards, André

Jazz
User
Posts: 63
Joined: 12-Aug-2005
# Posted on: 02-Oct-2007 16:35:28   

Ok, I found a quick workaround, placing a partial class in my mapping...


public partial class EntityCollection {
    private bool _MarkDeletedAfterRemoval = true;

    [XmlIgnore]
    public bool MarkDeletedAfterRemoval {
        get {
            return _MarkDeletedAfterRemoval;
        }
        set {
            _MarkDeletedAfterRemoval = value;
        }
    }

    protected override void PlaceInRemovedEntitiesTracker(EntityBase2 item) {
        if(_MarkDeletedAfterRemoval) {
            base.PlaceInRemovedEntitiesTracker(item);
        } else {
            if (RemovedEntitiesTracker == null) {
                return;
            }

            RemovedEntitiesTracker.Add(item);
        }
    }
}

when a RemovedEntitiesTracker Property is set, items that get removed are marked as being removed, thus resulting in a flat serialization. I added another property to skip that step. Now I can use the RemovedEntitiesTracker Collection as an argument for my WebService to remove the Entities from the Database.

Still I'd like to know if this is the best way doing it, got the impression that this solution is a bit awkward.

Regards, André