Print Page | Close Window

SaveChangesAsync(IEnumerable)??

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=1730
Printed Date: 13-Mar-2025 at 5:02pm


Topic: SaveChangesAsync(IEnumerable)??
Posted By: *Calsy
Subject: SaveChangesAsync(IEnumerable)??
Date Posted: 20-Apr-2010 at 11:53am

Hi All, Im currently in the process of doing the convert from 2009 to 2010 and have hit my first little snag.

Just wondering where the SaveChangesAsync with a list of entities has gone? Forgive me if im just having a blonde moment. Or has it been made obsolete. It is still in the help doco. But when in code i only have the following three options:
1. mgr.SaveChangesAsync()
2. mgr.SaveChangesAsync(UserCallback, UserState)
3. mgr.SaveChangesAsync(SaveOptions.UserCallback, UserState)
 
There aint any mgr.SaveChangesAsync(IEnumerable, UserCallback, UserState)???
 
Thanks



Replies:
Posted By: *Calsy
Date Posted: 20-Apr-2010 at 3:31pm
Little Help???


Posted By: WardBell
Date Posted: 20-Apr-2010 at 3:40pm

I'm looking right at it when I examine EntityManager in the VS Object Browser:

public IdeaBlade.EntityModel.EntitySaveOperation SaveChangesAsync(
    System.Collections.IEnumerable entities,
    [IdeaBlade.EntityModel.SaveOptions saveOptions = null],
    [System.Action<EntitySaveOperation> userCallback = null],
    [object userState = null])

Member of IdeaBlade.EntityModel.EntityManager

There it is, first parameter, the rest having defaults.
 
And then there is this:

public IdeaBlade.EntityModel.EntitySaveOperation SaveChangesAsync(System.Collections.IEnumerable entities)

Member of IdeaBlade.EntityModel.EntityManager

 


Posted By: ting
Date Posted: 20-Apr-2010 at 3:55pm
So , basically, convert your code from this:
mgr.SaveChangesAsync(IEnumerable, UserCallback, UserState)
 
To this:
mgr.SaveChangesAsync(IEnumerable, null, UserCallback, UserState)
 


Posted By: *Calsy
Date Posted: 20-Apr-2010 at 4:19pm
Hi, Ive tried the following lines (obcol = ObservableCollection of entities).
 
 
************

mgr.DefaultManager.SaveChangesAsync(ObCol, AddressOf UserSaved, Nothing)

mgr.DefaultManager.SaveChangesAsync(ObCol, nothing, AddressOf UserSaved, Nothing)
************
 
But they all error. Ive only got 3 different options for calling SaveChangesAsync in my ObjectBrowser, as follows.
 
 
 
None mention anything about IEnumerable.
 
???


Posted By: WardBell
Date Posted: 20-Apr-2010 at 7:18pm
Yikes.  We are looking to VB experts to help us understand why the VB compiler only shows (and compiles) 3 of the 5 SaveChangesAsync signatures. For some reason it will NOT recognize the two with IEnumerable as the first parameter. We hope to solve this mystery soon!


Posted By: WardBell
Date Posted: 20-Apr-2010 at 7:22pm
For the record, these are the SaveChangesAsync signatures of EntityManager as confirmed by Reflector.

 

(1)    Public Function SaveChangesAsync() As EntitySaveOperation

 

(2)    Public Function SaveChangesAsync(

  ByVal entities As IEnumerable) As EntitySaveOperation

 

(3)    Public Function SaveChangesAsync(

  ByVal userCallback As Action(Of EntitySaveOperation),

  ByVal Optional userState As Object = Nothing) As EntitySaveOperation

 

(4)    Public Function SaveChangesAsync(

  ByVal saveOptions As SaveOptions,

  ByVal Optional userCallback As Action(Of EntitySaveOperation) = Nothing,

  ByVal Optional userState As Object = Nothing) As EntitySaveOperation

 

(5)    Public Function SaveChangesAsync(

  ByVal entities As IEnumerable,

  ByVal Optional saveOptions As SaveOptions = Nothing,

  ByVal Optional userCallback As Action(Of EntitySaveOperation) = Nothing,

  ByVal Optional userState As Object = Nothing) As EntitySaveOperation

 

The VB compiler refuses to recognize #2 and #5, the signatures that take IEnumerable as the first parameter



Posted By: WardBell
Date Posted: 21-Apr-2010 at 12:36am
Figured out the issue. The cause is definitely our fault and we will make repairs for the next release (approximately 7 weeks from now). Meanwhile, I have a workaround which I think is not too painful.
 

What I discovered is that wherever there are two signatures that are the same AFTER REMOVING OPTIONAL PARAMETERS, the VB compiler disallows BOTH.

 
Our #2 and #5 EntityManager.SaveChangesAsync signatures are the same by VB's reasoning.

 

Deborah Kurata filled me in on the background

This is from the C# spec:

"If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters."

http://msdn.microsoft.com/en-us/library/dd264739%28VS.100%29.aspx - http://msdn.microsoft.com/en-us/library/dd264739(VS.100).aspx

This is from the VB documentation:

"A procedure with an
http://msdn.microsoft.com/en-us/library/09yx51zh.aspx -
http://msdn.microsoft.com/en-us/library/e18yd02w.aspx - http://msdn.microsoft.com/en-us/library/e18yd02w.aspx


So C# resolves it and VB won't.
 

Thanks, Deborah!

 
By the way, if you don't know Deborah ... you should. Here's her signature

Deborah Kurata

http://www.insteptech.com/ - Instep Technologies, Inc

Blog: http://msmvps.com/blogs/DeborahK - http://msmvps.com/blogs/DeborahK

Co-Chair: East Bay.NET user group

Microsoft MVP

I have a workaround for VB developers. You must create a C# class library project (if you don’t have one already) and add the following class to it:

 

using System;

using System.Collections;

 

namespace IdeaBlade.EntityModel {

 

  public static class EntityManagerExtensions {

 

    public static EntitySaveOperation SaveChangedItemsAsync(

      this EntityManager manager,

      IEnumerable entities,

      SaveOptions saveOptions = null,

      Action<EntitySaveOperation> userCallback = null,

      object userState = null) {

        return manager.SaveChangesAsync(entities, saveOptions, userCallback, userState);

    }

  }

}

 

You may then write:

 

mgr.SaveChangedItemsAsync(changeList)

 
Sorry for the surprise. Hope this tides you over for now.


Posted By: WardBell
Date Posted: 21-Apr-2010 at 10:36am

More musings on this subject.

Beth Massi got me wondering whether the VB compiler or the C# compiler takes the better approach to resolving the ambiguity.
 
I think VB has it right and the C# compiler has made a terrible choice.
 
VB and C# are statically typed languages (primarily). You choose a statically typed language because you want the compiler to tell you about problems or potential problems. The "right" behavior should be guided by this fundamental principle.
 
#2 and #5 are necessarily ambiguous. When the caller presents no parameters other than the IEnumerable, which method should the compiler choose?
 
What if #2 were implemented differently than #5? 
In DevForce 2010 today, #2 delegates to #5 with null arguments for the optional params. But it's not hard to imagine changing the default values for #5 someday, subtly breaking the current semantics of #2.
The caller has no reason to believe that writing
 
  mgr.SaveChangesAsync(list); // #2
 
will behave differently than
 
  mgr.SaveChangesAsync(list, null, null, null); // #5
 
But there's a risk of just that difference.
 
I can't see why anyone would want to write code that took advantage of this difference.
 
Should the developer "just know" that C# picks #2. What's the population of C# developers who could anticipate this problem? The question is rhetorical; we all know the answer: "a handful".
 
VB forestalls this error. Kudos to VB. Shame on C#.
 


Posted By: *Calsy
Date Posted: 21-Apr-2010 at 11:15am
Hi Ward, As always you are the oracle. Implemented, tested and works a treat.
 
I dont think ive ever heard a C# programmer give props to VB, must have tasted a little weird typing it out i would think.
 
Thanks



Print Page | Close Window