Print Page | Close Window

Minimum number of related entities

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce 2010
Forum Discription: For .NET 4.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=2325
Printed Date: 29-Jul-2026 at 10:05am


Topic: Minimum number of related entities
Posted By: bigme
Subject: Minimum number of related entities
Date Posted: 21-Nov-2010 at 6:06pm
On an Order entity, I have a collection of OrderDetails. I want there to be at least one OrderDetail on an Order, so I have the following verifier:

private static Verifier GetAtLeastOneOrderDetailVerifier()
            {
                string description = "An order must have at least one line:";

                DelegateVerifier<Order> v = new DelegateVerifier<Order>(description, (o, tc, vc) =>
                    {
                        return new VerifierResult(o.OrderDetails.Count(od => od.EntityAspect.EntityState == EntityState.Added
                          || od.EntityAspect.EntityState == EntityState.Modified
                          || od.EntityAspect.EntityState == EntityState.Unchanged) > 0);
                    });
               return v;
            }

This works ok for the client but fails at the server (the Save fails with the message above).

How can I test that the Order has at least one OrderDetail when the order is saved? Note that this could be a preexisting OrderDetail or a new one.

Dave.



Replies:
Posted By: DenisK
Date Posted: 22-Nov-2010 at 1:35pm
Hi bigme;

You could intercept the validation process before the save by creating your own EntityServerSaveInterceptor. For example:

public class CustomEntityServerSaveInterceptor : EntityServerSaveInterceptor {
    
    protected override bool ValidateSave() {

      var orderEntities = this.EntityManager.FindEntities<Order>(EntityState.AllButDetached);
      foreach (var order in orderEntities) {
        var verifierResultCollection = this.EntityManager.VerifierEngine.Execute(order);
      }
      return base.ValidateSave();
    }

Please try the above code and see what you get.


Posted By: bigme
Date Posted: 22-Nov-2010 at 3:37pm
Thanks Denis,

That lets me see what's happening, and I can see several problems, but the main one is that when an Order entity is edited and saved it doesn't send back its OrderDetails collection (understandably) so unless the OrderDetails have also been updated/added then my simple count of related OrderDetails won't work. 

I can see three solutions to this: 

  1. write a server-side validator that queries the database for existing OrderDetails (not sure how I'd do that -- can I access Entity Framework from the Verifier, server-side only? Sounds messy); 

  2. force the entire set of OrderDetails to be returned when the client saves (by setting a last edited date or something);

  3. or suppress server-side validation for this rule.

I like the last solution as, in this case, there is no real need to run the validation server-side. However, it isn't clear to me from the documentation how to go about that. In Server-Side Validation the documentation says "but it is not required that the same verifiers be defined on both client and server. " but doesn't mention how to define verifiers for one side or the other but not both. What am I missing?

Dave.


Posted By: DenisK
Date Posted: 22-Nov-2010 at 4:40pm
Dave;

I was able to get the expected behavior without any of the workaround.

"when an Order entity is edited and saved it doesn't send back its OrderDetails collection"

This should still send back its OrderDetails collection even when the collection is not modified. I have tested this. What version of DF2010 are you using?

"1. write a server-side validator that queries the database for existing OrderDetails (not sure how I'd do that -- can I access Entity Framework from the Verifier, server-side only? Sounds messy);"

I'm not sure if accessing the Entity Framework from the Verifier is possible. However, you can query the database from the server side ValidateSave method using the following:

var orderDetailsQuery = new EntityQuery<OrderDetail>("OrderDetails", this.EntityManager);
var orderDetailsResults = this.EntityManager.ExecuteQuery(orderDetailsQuery);

"3. or suppress server-side validation for this rule."

Please see the following post on how to do that.

http://www.ideablade.com/forum/forum_posts.asp?TID=2298&KW=VerifierEngine&PID=9094&title=cant-seem-to-stop-the-verification-engine#9094 - http://www.ideablade.com/forum/forum_posts.asp?TID=2298&KW=VerifierEngine&PID=9094&title=cant-seem-to-stop-the-verification-engine#9094


Posted By: bigme
Date Posted: 24-Nov-2010 at 3:12pm
Denis,

Sorry for the delay. I wanted to eliminate some complexities from the app I'm working on and try to reproduce the problem in a simpler example, which I have managed to do.

In my example I have a Northwind db with Orders and Order Details. A verifier checks that at least one Order Detail is present. I have done nothing special so far (that is, I haven't tried any of the techniques discussed above). If I add a new Order Detail and save, all is well. But if I edit the Order Date and save then the verifier on the client passes OK, but the verifier on the server complains that there are no Order Details.

If I set a breakpoint and look at what the verifier has to work with on the server then it's obvious -- there are no Order Details on the Order. I am not sure that this is a bug, but it doesn't seem consistent with your statement about getting the expected behavior -- maybe we're at cross-purposes here?

It is frequently the case that you want verifiers to run client side only, eg where you have legacy data that breaks the rules, or when the conditions for a valid value change from version 1.1 to 1.2.

It would be very nice if verifiers had a flag to indicate whether they should execute client side, server side, or both. 

Thinking about this further, it is not really a client/server issue, but rather a new data/old data issue. Still, having control over where verifiers execute via a simple flag would be nice.

BTW I am happy to upload my example if you want to take a look.

Dave.


Posted By: bigme
Date Posted: 24-Nov-2010 at 3:33pm
Denis,

I am using DevForce version 6.0.6.1, and SL 4.

Dave.



Posted By: DenisK
Date Posted: 24-Nov-2010 at 4:21pm
Dave;

Thanks for the info. 

Your verifier flag option has been submitted as a feature request.

Yes, could you please upload your example? Thanks.


Posted By: bigme
Date Posted: 25-Nov-2010 at 4:31pm
Denis,

I have uploaded the project example to a public folder on a SkyDrive. Never used it before so let me know if it doesn't work as expected but you should be able to download from here:

http://cid-faf267b007920a0e.office.live.com/self.aspx/.Public/SLDFTest/slTest.zip

1. Adjust web.config database connection to point to a Nortyhwind db. Compile and run.
2. Select a Customer (eg Alfreds). Customers orders are displayed, together with Order Details for the selected order.
3. Change some data on the Order (eg OrderDate)
4. Click Save.

==> Server Error: Order Must have at least one line.

If you set a breakpoint on the ValidateSave() override in CustomEntityServerSaveInterceptor then you can see that there are no 
Order_Details for the Validator to validate.
Dave.


Posted By: DenisK
Date Posted: 01-Dec-2010 at 12:54pm
Hi bigme;

I've confirmed that this was a bug in 6.0.6.1 and has been fixed in 6.0.7


Posted By: bigme
Date Posted: 01-Dec-2010 at 1:09pm
Denis,

Thanks for that.

I believe 6.0.6.1 is the current release? Do you have a release date for 6.0.7?

Dave.


Posted By: DenisK
Date Posted: 01-Dec-2010 at 1:18pm
6.0.7 is scheduled to be released on Dec 8th.



Print Page | Close Window