none
Change POCO Template to support WCF Test Client with Collections RRS feed

  • Question

  • The POCO template/code generator is fantastic.  It works great and I am loving it.

     

    I would like to make a suggestion however.  I am trying to expose my POCO objects via WCF.  But when I use the WCF Test Client, any collections I have fail when an object is inserted into them.  It gives the following error message:

         Collection was of a fixed size.

    The fix is fairly simple.  Add these 3 lines of code to the EntityNameHereModel.cs file:

     public FixupCollection(List<T> list) : base(list) { }
     public FixupCollection(IEnumerable<T> list) : base(list) { }
     public FixupCollection() { }

    Then in the EntityNameHere.cs file change any setters that have this line in them:

     _entityNameHere = value;

    To this:

     _entityNameHere = new FixupCollection<EntityTypeHere>(value);
    

    That is all that is needed to ensure that actual collections (not arrays) are used in dealing with the data.

     

    I would like to suggest that this change (or one like it) be considered for the actual template.

     




    Tuesday, July 5, 2011 10:35 PM

Answers

  • Well..

    Your original suggestion to change will actually only benefit WCF test client, in applications that passes a real FixupCollection to the setter will loose functionality like subscribing CollectionChanged event if they do this before they sets the collection (FixupCollection inherits ObservableCollection), which is a bad idea. I'm actually a bit suprised that the navigation properties in POCO is ICollection, in STE they return a TrackableCollection to avoid people setting incorrect types.

    Using a type other than FixupCollection in a navigation property is actually a bad idea since it won't fix links between the primary object and their foreign objects.

    In your last post were you suggest checking if it is an array and then create a FixupCollection of it, and otherwise leave it alone will however limit this problem to only arrays.

    Generally, I would not recommend you to ever use anything else than a FixupCollection as type with navigation properties.

    Now this is only academic for you, but I felt I had to explain it a bit :)

     


    --Rune
    • Marked as answer by Vaccanoll Wednesday, July 6, 2011 8:33 PM
    Wednesday, July 6, 2011 8:20 PM

All replies

  • I like T4 template too, you should customize the tempalate: http://blogs.msdn.com/b/adonet/archive/2009/07/22/customizing-t4-templates.aspx

     


    I am fish.
    Wednesday, July 6, 2011 4:42 PM
  • I did customize the template.

    I am just saying that it would be nice to have this as the default for future uses of the template (so I don't have to customize every time I use it).

    Wednesday, July 6, 2011 4:54 PM
  • Hi,

    Have you looked at Self-Tracking Entities?

    Self-Tracking Entities (http://msdn.microsoft.com/en-us/library/ff407090.aspx) is designed specific for use with WCF.

     


    --Rune
    Wednesday, July 6, 2011 5:14 PM
  • Yes (I just did)

    That template has the same problem.


    An Array and fit in those collections, but it does not implement everything right.  So when you try to add to it it fails.
    Wednesday, July 6, 2011 5:41 PM
  • This is strange..

    I'm using this and it works for me.

    Can you give a code example on what you do?


    --Rune
    Wednesday, July 6, 2011 6:18 PM
  • Sure:

    I have a patient object that has an address navigation property..

    When I wire those POCOs up to my WCF Service (ie soap)

    [OperationContract]
    bool RegisterPatient(Patient patient);
    

     And run the WCF Test Client against that (and fill in both the Patient and the Address data) I get the error I indicated above:

         Collection was of a fixed size.

    I get this error when I hit this line of code in Patient.cs:

    Address.Patients.Add(this);
    

    As I said above, an Array can be used as an ICollection.  But it does not get all the implementations right.  That is why this exception is thrown. If you are coding your own client you can easily use collections instead of arrays.  But there is no way (that I know of) to tell WCF Test Client to use collections instead of arrays. 

    Note: My suggested code could also check to see if the ICollection is an array before calling new.

    Note II: This issue is currently academic to me.  We decided that the POCO template does not give enough control over the data contract.  I need to hide foreign keys (and other server side stuff) from the client viewable data contract and the only way to do that is to modify the T4 template extensively.  Because of that we are going to go with normal Entity Framework code generation and manually generated Data Contracts.  (I say this so you don't expend too much effort for this issue on my behalf.)

    Wednesday, July 6, 2011 7:21 PM
  • Well..

    Your original suggestion to change will actually only benefit WCF test client, in applications that passes a real FixupCollection to the setter will loose functionality like subscribing CollectionChanged event if they do this before they sets the collection (FixupCollection inherits ObservableCollection), which is a bad idea. I'm actually a bit suprised that the navigation properties in POCO is ICollection, in STE they return a TrackableCollection to avoid people setting incorrect types.

    Using a type other than FixupCollection in a navigation property is actually a bad idea since it won't fix links between the primary object and their foreign objects.

    In your last post were you suggest checking if it is an array and then create a FixupCollection of it, and otherwise leave it alone will however limit this problem to only arrays.

    Generally, I would not recommend you to ever use anything else than a FixupCollection as type with navigation properties.

    Now this is only academic for you, but I felt I had to explain it a bit :)

     


    --Rune
    • Marked as answer by Vaccanoll Wednesday, July 6, 2011 8:33 PM
    Wednesday, July 6, 2011 8:20 PM
  • Thanks for the reply Rune,

    I would have been happy to use a FixupCollection, but the Microsoft WCF Test Client does not give that option (it is hard coded to use arrays).

    I appreciate the reply even if I will not be using it.  I linked here from a stack overflow question where the user was also getting the Collection was of  a fixed size error, so your reply may help future searchers and other users.

    And you never know, I may end up using the POCO template after all.  I am at Proof of Concept level only right now.


    Wednesday, July 6, 2011 8:33 PM
  • Hello,

     I was previously testing with EF4 (tt template 4x POCO with WCF support). I did some customization thanks to Julie Lerman posts and managed to get rid of the stupid serialization issue that forces my client to retrieve navigation collection as fixed sized arrays and results in the "Collection was of a fixed size" error described above. I was kind of magic for me...

    Now I moved to EF5 with template "EF 5.x DbContext Generator with WCF Support". Error is back ! I'm new to EF and WCF and don't really understand what's involved here. I'm looking for a good practice for working with WCF and EF5 in a disconnected scenario, and actually it's driving me nuts !

    Apparently the solution to this with EF4 had something to see with FixUpCollection ! But what if I want to use this 5x template as is (without FixUpCollection)? Is there something to do in WCF config (client side and/or server side) to get rid of this issue ?

    Arnaud.

    Friday, January 24, 2014 6:15 PM