New Posts New Posts RSS Feed: SaveChangesAsync(IEnumerable)??
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

SaveChangesAsync(IEnumerable)??

 Post Reply Post Reply
Author
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post Topic: SaveChangesAsync(IEnumerable)??
    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
Back to Top
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post Posted: 20-Apr-2010 at 3:31pm
Little Help???
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post 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

 
Back to Top
ting View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 27-Mar-2009
Location: San Francisco
Posts: 427
Post Options Post Options   Quote ting Quote  Post ReplyReply Direct Link To This Post 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)
 
Back to Top
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post 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.
 
???
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post 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!
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post 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

Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post 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(VS.100).aspx

This is from the VB documentation:

"A procedure with an
Optional (Visual Basic) parameter is equivalent to two overloaded procedures, one with the optional parameter and one without it. You cannot overload such a procedure with a parameter list corresponding to either of these. The following declarations illustrate this."

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

Instep Technologies, Inc

Blog: 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.


Edited by WardBell - 21-Apr-2010 at 12:38am
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post 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#.
 


Edited by WardBell - 21-Apr-2010 at 10:37am
Back to Top
*Calsy View Drop Down
Groupie
Groupie


Joined: 02-Feb-2009
Location: Australia
Posts: 69
Post Options Post Options   Quote *Calsy Quote  Post ReplyReply Direct Link To This Post 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
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down