none
GetChangeSet throws exception when FK has been nulled out

    Question

  • Hi,

     

    If a non-nullable relationship is nulled out, then I call GetChangeSet, I get an error like this:

     

    An attempt was made to remove a relationship between a X and a Y. However, one of the relationship's foreign keys (X.A) cannot be set to null

     

    This is a real nuisance. Yes, I can see why this kind of error must happen on SubmitChanges, but I'm not trying to submit any changes.  I'm just trying to find out which objects the user has edited (so I can run some validation on them, as it happens).  I would think that the system could tell me which objects have been edited regardless of whether or not they satisfy mandatory relationships.

     

    Is there any way that I can get a change set without triggering this error?

     

    Failing that, is there any supported way to get a list of all the objects "in" the DataContext?  (If I can't get a change set, I could do a workaround where I look at all the objects).

     

    John

    Monday, April 28, 2008 11:57 PM

All replies

  • The ironic thing is that I'm getting the changed objects so that I can check their mandatory fields are set.  Unfortunately, when mandatory foreign-key-style relationships are missing, I can't even get the list of changed objects.

     

    Anyone?

     

    Wednesday, April 30, 2008 8:09 PM
  • You should not be getting the exception. It must be a bug. 

     

    Friday, May 02, 2008 3:58 PM
    Moderator
  • Thanks for confirming that. 

     

    Do you need any more info from me?

     

    Is there any place I can see the status of this bug (e.g. on connect.microsoft.com)?  Our current project will be affected by the timing of the fix, so I'd like to be able to check the status from time to time.

     

    John

     

    Sunday, May 04, 2008 8:43 PM
  • Yes please log your bug at connect and you will be able to track the progress.

     

    Friday, May 09, 2008 11:21 PM
  • Hi John,

    You mentioned in your earlier threads that 1 of the relationship's foreign keys cannot be set to null.  To clarify, is this relationship mapped to a composite key?

     

    Thanks,

    Kathy

    An attempt was made to remove a relationship between a X and a Y. However, one of the relationship's foreign keys (X.A) cannot be set to null

    Saturday, May 10, 2008 12:17 AM
  • Kathy,

     

    We don't have any composite keys in our system, so no, it's not a composite key.

     

    John

    Sunday, May 11, 2008 8:03 PM
  • Hi John,

     

    I'm not able to reproduce this on my side.  Can you please send us further information on your repro?  Your actual schema and the actual steps you took to get this exception? 

    This would help us quickly track down your issue and we can investigate it from there.

     

    Thanks for your help.

    Kathy

    Monday, May 12, 2008 9:14 PM
  • Funny you should post this now.  Just a couple of hours ago I was looking over a colleague's shoulder and saw it working properly on his screen too.  I think the way forward will be for me to investigate the differences between his case and the one that sparked the bug report.  (Both are reproducable here).  That may work better than sending you schema and code because both are so extensive. It's an enterprise level app, with a significant in-house infrastructure that sits on top of LINQ-to-SQL.  It would be difficult to strip code and schema down to something small enough to send to you, unfortunately.

     

    So, if its OK with you, I'll investigate this a little more here during the next few weeks (am very busy, hence the long-ish timeframe!).  Once I have an update, I'll post in reply to this thread.  If I don't manage to make any progress, I will have to look at stripping down the code and schema to a managable size, to send through as you suggest.

     

    Thanks to you and Matt for confirming that this is indeed a bug, rather than intended behaviour. 

     

    John

    Tuesday, May 13, 2008 12:22 AM
  • Hi John,

     

    Thank you for sending us feedback on this issue you are seeing.  We have more targeted tests in this area that perform a GetChangeSet when FK is nulled out.  In our simplistic testing, we don't see this issue. 

    Would it be ok that I close on the connect bug for the time being until you get a chance to look at the issue again?  When you get a chance to track down the difference, please re-activate the bug with your reproduction. The team would like to investigate your issue further with more information.

     

    Thank you,

    Kathy

    Tuesday, May 13, 2008 12:32 AM
  • Yes, that's fine.

     

    Tuesday, May 13, 2008 2:00 AM
  • Kathy,

     

    I just spoke to one of my colleagues.  He may have saved both of us a lot of work.  He's identified a scenario in which the bug can be reproduced here.  It goes like this:

     

    1. Create a new entity.  Without setting any of its fields, add it to a parent collection.  (E.g. add a brand new Order to a Customer).
    2. Set a property that corresponds to a foreign key on the new entity (e.g. set Order.Product to a product)
    3. Call GetChangeSet().  This works.
    4. Clear the property that corresponds to the foreign key (e.g. set Order.Product to null)
    5. Call GetChangeSet() again.  This blows up with the exception.

    At no time in this sequence do we call SubmitChanges().

     

    Is the bug reproducable for you, with that sequence of events?

     

    John

    Tuesday, May 13, 2008 2:25 AM
  • Hi John,

     

    Thanks for getting back to me.  I've tried this on my end, however wasn't able to reproduce the issue.

    My repro contains an intermediate table OrderDetails as Linq To SQL supports M:N tables with an intermediate table.

     

    Here's the repro:

    Code Snippet

    Northwind db = new Northwind(conStr);

    Order a = new Order();

    Customer c = db.Customers.First();

    c.Orders.Add(a);

    Product p = db.Products.First();

    OrderDetail od = new OrderDetail();

    od.Quantity = 1; //needed to add this due to constraint.

    od.Order = a;

    od.Product = p;

    db.SubmitChanges();

     

    a.OrderDetails.Remove(od);

    p.OrderDetails.Remove(od);

    od.Product = null;

    db.GetChangeSet();

     

     

     

    -No exception gets thrown.

    Tuesday, May 20, 2008 9:51 PM
  • Hi John,

     

    I can't reproduce the problem either. I think It would be good if you could provide the stack trace though.

     

    Wednesday, May 21, 2008 1:41 PM
  • Thanks Kathy and Sidar. 

     

    I'll post more info here within the next few days.

     

    John

     

    Wednesday, May 21, 2008 10:20 PM
  • Kathy,

     

    I pasted your code into my IDE, dragged the appropriate Northwind tables into the LINQ-to-SQL designer, ran your code and got an exception on the last GetChanges.  (!)  In other words, your code does reproduce the bug on my machine.

     

    So, the question is, why does it work for you and fail for me.  I'll attach my complete project, as a zip file, so you can investigate further.  In fact, I'll attach both source and the compiled binaries.  I'll attach both to the bug, that is logged here -- https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=343378 -- rather than to this message

     

    Output from the program looks like this on my machine:

     

    Code Snippet

    Setting environment for using Microsoft Visual Studio 2005 x86 tools.

    C:\Work\Spikes\LinqExceptionTest\TestSettingToNull\bin\Debug>TestSettingToNull.exe
    Running on .NET version: 2.0.50727.1433

    Unhandled Exception: System.InvalidOperationException: An attempt was made to remove a relationship between a Order and
    a OrderDetail. However, one of the relationship's foreign keys (OrderDetail.OrderID) cannot be set to null.
       at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData()
       at System.Data.Linq.ChangeProcessor.GetChangeSet()
       at System.Data.Linq.DataContext.GetChangeSet()
       at TestSettingToNull.Program.RunTest() in C:\Work\Spikes\LinqExceptionTest\TestSettingToNull\Program.cs:line 35
       at TestSettingToNull.Program.Main(String[] args) in C:\Work\Spikes\LinqExceptionTest\TestSettingToNull\Program.c
    s:line 13

     

     

     

    Possible differences I can think of are:

     

    (a) Different .net framwork versions.  I have 2.0.50727.1433 and, as far as I know, I have no service packs.  If that's the case, then my binary should work on your machine (but fail on other machines at Microsoft that have the exact same framework version as me).

    (b) Differences in the generated mapped classes (e.g. perhaps you have an IDE patch and I don't).  If that's the problem, then my binary should fail on your machine.

    (c) Some other weird thing..... ;-)


    John

    Sunday, May 25, 2008 9:57 PM
  • Wednesday, July 30, 2008 3:44 AM
  • i have this same issue.  basic shuttlebox of a ui.  picking Xs that are associated with the primary object Y.  these associations are added to a many-to-many table in the form [schema].[XY]. 

    To make the following more clear, in this case X is a advertisement aka 'Feature' (e.g. an ad for Direct TV or Pepsi) and Y
    is a
    'Personality' (e.g. Jessica Simpson, Britney Spears).  So Britney Spears gets the axe from pepsi and we use the shuttle box to reflect that by removing her affiliation:

     

    the following code is called to remove one such association behind the scenes:

    // remove the object

              m_Feature.FeaturePersonality.Remove(entity);

    Where m_Feature is an instance of a Linq to SQL generated object, FeaturePersonality its EntitySet collection of the Many to Many i described

    this is at the UI level where we are making a number of changes on m_Feature that we need to persist to DB in one shot.  we can not have a data processing scenario where each individual change is made and persisted independently - i.e. remove britney spears and then separately persist the fix for the fact that somebody misspelled Pepsi as Pipsi in the initial data entry.

    the next time GetChangeSet is called i get a big blowup

    let me pause and say i note this as different from the issues covered in https://connect.microsoft.com/VisualStudio/feedback/Validation.aspx?FeedbackID=343378 because this seems to be all about removing an FK.  I need to remove a many to many object.  I posed the fugazzi note there regarding can be null.

    this is a real problem since in this complex, almost disconnect save, we have the most likely scenario for a concurrency issue, which - which was my point of getting a change set.  so now that i use the totally interim resolution of catching these exceptions, i cant concurrency check anything to do with a primary entity if any of the many-to-many linked objects have had items removed from the respective EntitySet collection.

    at this point its just 'Help... Please'.  Bug?, Misuse of linq? the change / concurrency tracking was a selling point for linq.  in the state i described the net functionality implemented is LESS than other ORM platforms available.

    gracias

    - john

    the following is my exception info / stack trace when the GetChangeSet bomb drops:

    Code Snippet
     
     
    (i dont know whats up with this snipit box - sorry)
     
    An attempt was made to remove a relationship between a Feature and a FeaturePersonality. However, one of the relationship's foreign keys (FeaturePersonality.FeatureId) cannot be set to null.
     

     

       at System.Data.Linq.ChangeTracker.StandardChangeTracker.StandardTrackedObject.SynchDependentData()
       at System.Data.Linq.ChangeProcessor.GetChangeSet()
       at System.Data.Linq.DataContext.GetChangeSet()
       at Comptrk.SOLUS.DataContexts.Managers.ResolutionManager.Get[TSource](IEnumerable`1 collection) in C:\Documents and Settings\john_gibbons\My Documents\Visual Studio 2008\Projects\Comptrk.SOLUS\Comptrk.SOLUS.DataContexts\Managers\ResolutionManager.cs:line 270
       at Comptrk.SOLUS.DataAccess.Servers.ViralAdvertisementDataServer.GetViralAdvertisementById(Int32 id) in C:\Documents and Settings\john_gibbons\My Documents\Visual Studio 2008\Projects\Comptrk.SOLUS\Comptrk.Solus.DataAccess\Servers.Generated\ViralAdvertisementDataServer.Generated.cs:line 161
       at Comptrk.SOLUS.BusinessLogic.DataAdapters.ViralAdvertisementDataAdapter.GetDeepLoadedViralAdvertisementById(Boolean recursive, Int32 id) in C:\Documents and Settings\john_gibbons\My Documents\Visual Studio 2008\Projects\Comptrk.SOLUS\Comptrk.SOLUS.BusinessLogic\DataAdapters.Generated\ViralAdvertisementDataAdapter.Generated.cs:line 226
       at Comptrk.SOLUS.Client.UserControls.ViralAdvertisementDetailSearch.m_EditMCButton_Click(Object sender, RoutedEventArgs e) in C:\Documents and Settings\john_gibbons\My Documents\Visual Studio 2008\Projects\Comptrk.SOLUS\Comptrk.SOLUS.Client\UserControls\ViralAdvertisementDetailSearch.xaml.cs:line 694
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.Controls.Primitives.ButtonBase.OnClick()
       at System.Windows.Controls.Button.OnClick()
       at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
       at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
       at System.Windows.UIElement.CrackMouseButtonEventAndReRaiseEvent(DependencyObject sender, MouseButtonEventArgs e)
       at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       at System.Windows.Input.InputManager.ProcessStagingArea()
       at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
       at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
       at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
       at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at Comptrk.SOLUS.Client.App.Main() in C:\Documents and Settings\john_gibbons\My Documents\Visual Studio 2008\Projects\Comptrk.SOLUS\Comptrk.SOLUS.Client\obj\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

    Thursday, August 14, 2008 8:59 PM
  • this also fails under the same circumstances but even with deleteonnull = true. my other post details why canbenull on an fk property that remains non nullable at the db is not viable. this pretty much rules out both workarounds suggested from connect # 343378

    Code Snippet

    m_DataContext.Refresh(RefreshMode.OverwriteCurrentValues,



    Friday, August 15, 2008 12:45 AM
  • I wonder if this is fixed in SP1 for .NET 3.5? I haven't had time to set up a suitable test environment yet.  As anyone tried? Can anyone from Microsoft confirm whether or not it has been fixed?

     

    John

    Sunday, August 17, 2008 8:30 PM
  • I can confirm this wasn't addressed - Kathy's sample repros here on SP1.

     

    Out of curiosity what version of SQL server are you connecting to?

     

    [)amien

    Tuesday, August 19, 2008 8:34 PM
    Moderator
  • Hi Damien,

     

    Thanks for letting us know the status of the issue.  Shame it wasn't addressed.

     

    I am running SQL Server 2005.  It reports its version information as follows:

     

    9.00.3068.00 SP2 Developer Edition

     

    John

    Wednesday, August 20, 2008 5:51 AM
  • Hi,

    I also had the same problem, and looks like there is no valid solution till now. What I was able to find somewhere in some forum (I would like to quote but I don't really remember where) is possibility to go around it.

    Instead of only deleting inserted, like I'm doing in my DataContext RevertChanges method,

     

        public static void RevertChanges(this DataContext dc, ChangeSet oldChanges) {
          ChangeSet changes = dc.GetChangeSet();
          //Insert
          foreach (object objInsert in changes.Inserts) {
            if (!oldChanges.Inserts.Contains(objInsert)) {
              dc.GetTable(objInsert.GetType()).DeleteOnSubmit(objInsert);
            }
          }
          //Update
          foreach (object objUpdate in changes.Updates) {
            if (!oldChanges.Updates.Contains(objUpdate)) {
              dc.Refresh(RefreshMode.OverwriteCurrentValues, objUpdate);
            }
          }
          //Delete
          foreach (object objDelete in changes.Deletes) {
            if (!oldChanges.Inserts.Contains(objDelete)) {
              dc.GetTable(objDelete.GetType()).InsertOnSubmit(objDelete);
              // GetChangeSet throws exception when FK has been nulled out
              // therefore it is needed to undo member changes on delete.
              UndoMemberChanges(dc, objDelete);
            }
          }
        }
    

     

     

    you should also undo changes made in the context itself.

     

     

        private static void UndoMemberChanges(DataContext dc, object obj) {
          Dictionary<string, List<MemberInfo>> associations = GetTypeAssociations(obj.GetType());
          ModifiedMemberInfo[] mmis = dc.GetTable(obj.GetType()).GetModifiedMembers(obj);
          if (mmis.Length > 0) {
            // Get GetTable method
            MethodInfo miGetTable = dc.GetType().GetMethod("GetTable",
            System.Reflection.BindingFlags.Instance | BindingFlags.Public,
            null, Type.EmptyTypes, null);
            foreach (ModifiedMemberInfo mmi in mmis) {
              Type propType = (mmi.Member as PropertyInfo).PropertyType;
              if (associations.ContainsKey(mmi.Member.Name)) {
                // do not undo modified member but redo it's assoications
                // that will automatically restore the modified member
                List<MemberInfo> members = associations[mmi.Member.Name];
                foreach (MemberInfo mi in members) {
                  Type associatedType = GetMemberType(mi);
                  // Get generic GetTable method
                  MethodInfo miGenericGetTable = miGetTable.MakeGenericMethod(new Type[] { associatedType });
                  // Invoke to get table
                  IQueryable table = miGenericGetTable.Invoke(dc, null) as IQueryable;
                  // Create condition to single out associated object
                  ParameterExpression fkParam = Expression.Parameter(associatedType, "fkParam");
                  Expression left = Expression.Property(fkParam,
                    // TODO: name of this method should be found in AssociationAttribute
                        associatedType.GetMethod("get_ID"));
                  left = Expression.Convert(left, propType);
                  Expression right = Expression.Constant(
                        // associated object's ID
                        mmi.OriginalValue, propType);
                  Expression equal = Expression.Equal(left, right,
                        false,
                        propType.GetMethod("op_Equality") );
                  LambdaExpression exprId = Expression.Lambda( 
                    equal,
                    new ParameterExpression[] { fkParam }
                  );
                  // create method call expression
                  MethodCallExpression exprCall = System.Linq.Expressions.Expression.Call(
                    typeof(Queryable), "Single", new Type[] { table.ElementType },
                    table.Expression, exprId);
                  object associatedObj = table.Provider.Execute(exprCall);
                  // Set associated object
                  SetMemberValue(obj, mi, associatedObj);
                }
              } else {
                // undo change by setting modified member to OriginalValue
                SetMemberValue(obj, mmi.Member, mmi.OriginalValue);
              }
            }
          }
        }
    

     

     

    For that you will also need to get type associations, and you can get them using the following:

     

     

        private static Dictionary<string, List<MemberInfo>> GetTypeAssociations(Type type) {
          if (!typeAssociations.ContainsKey(type)) {
            Dictionary<string, List<MemberInfo>> result = new Dictionary<string, List<MemberInfo>>();
            foreach (MemberInfo mi in type.GetMembers()) {
              object[] attrs = mi.GetCustomAttributes(typeof(AssociationAttribute), true);
              if (attrs.Length > 0) {
                AssociationAttribute attr = attrs[0] as AssociationAttribute;
                List<MemberInfo> members = null;
                if (result.ContainsKey(attr.ThisKey)) {
                  members = result[attr.ThisKey];
                } else {
                  members = new List<MemberInfo>();
                  result.Add(attr.ThisKey, members);
                }
                members.Add(mi);
              }
            }
            typeAssociations.Add(type, result);
            return result;
          }
          return typeAssociations[type];
        }
    

     

     

    What can also be done is to undo member changes on reverting the updates, or to clean association on reverting the inserts,

     

     

        private static void ClearAssociations(object obj) {
          Dictionary<string, List<MemberInfo>> associations = GetTypeAssociations(obj.GetType());
          foreach (List<MemberInfo> members in associations.Values) {
            foreach (MemberInfo mi in members) {
              SetMemberValue(obj, mi, null);
            }
          }
        }
    

     

     

    but I don't think this is necessary. Someone please correct me if I'm wrong.

     

    Regards,

    M.

     

     

     

    • Proposed as answer by MAdamov Monday, November 15, 2010 12:58 PM
    Monday, November 15, 2010 12:56 PM
  • Hi there, 

    I know this thread is pretty mature now but, since I got this error just a while ago I wonder if there was any fix introduced by MS ?

    I use VS2012, .Net 4 framework and a xml mapping file (no designer suff).  I was reading the whole thread and saw some stuff I expirienced myself.

    I just have a scenario where the user can add a entity with associations and delete it right after adding without submitting the changes. This will cause the error we talk about here. If the user submits the changes between adding and deleting the entity again it works just fine ,this is the case we saw on kathys post further down. There she stated she can't reproduce the exception (because she made a submitchanges). I tried lot of crap to get it to work but Im just stuck and well lets be serious it shouldn't be a problem at all. So maybe Im missing something that someone can point me to, I made the DeleteonNull stuff, I tried to set all the associations to null nothing worked for me.

    if nothing has changed over the past 5 years it would be just another MS fail :/

    so I hope I just miss something and we have a solution to thsi problem that doesnt cause me to reinvent the wheel again

    Regards

    Friday, March 08, 2013 8:55 AM