Locked Oracle to SqlExpress

  • Montag, 29. Juni 2009 04:44
     
     
    My case is as the following:
    1-The back end database is oracle.
    2-The client is sqlServer 2005 Express edition
    3-I need to get a fresh copy of certain tables periodically(Snapshot)
     ------------------------------------------------------
    |My problem is with the sqlExpressSyncProvider|
     ------------------------------------------------------
    .I used the sqlExpressSyncProvider from the sample,since i am using an oracle database as the back end, the schema information retrieved from the Oracle server database is not enough for SqlCe to create the tables. In order to fix that, I need to abandon the automatic schema retrieval logic that the server provider uses and instead supply a SyncSchema object to the provider with all mapping information (as in the oracle offline demo http://www.syncguru.com/projects/SyncServicesDemoOracle.aspx),if i don't do that ,nothing work and an error message appears to me.
    .In the sqlExpressSyncProvider sample,there is class inherits from the dbserversyncprovider called (sqlExpressSyncProvider ),in its implemntation the createschema function is not implemented they throw exception(not supported exception in this version)
    .when i run my application using the sqlExpressSyncProvider  it gives me a not supported exception(createschema)
    .when i comment the throw exception everything works fine and the synhonization occurs,but no data inserted locally to the sqlexpress database
    .I found a fix in this url:http://www.8bit.rs/blog/?p=23

    public override SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession)
    {
    //Map SyncDirection from client POV to our internal server POV

    foreach (SyncTableMetadata tableMetadata in groupMetadata.TablesMetadata)
    {
    if (tableMetadata.SyncDirection == SyncDirection.DownloadOnly || tableMetadata.SyncDirection == SyncDirection.Snapshot)
    {
    //This SyncDirection DownloadOnly/Snapshot is from a Client point of view. But our client is inturn a Server provider. Hence switch this to UploadOnly
    tableMetadata.SyncDirection = SyncDirection.UploadOnly;
    }

    else if (tableMetadata.SyncDirection == SyncDirection.UploadOnly)
    {
    //This SyncDirection UploadOnly is from Client POV. But our client is inturn a Server provider. Hence switch this to DownloadOnly
    tableMetadata.SyncDirection = SyncDirection.DownloadOnly;
    }
    }

    // neet to set the LastReceivedAnchor as the LastSentAnchor since
    // DbServerSyncProvider operates from the server's perspective, so
    // we swap the two fields temporarily.
    // Note that even if we do this, the NewAnchor value will be the one
    // from the server, not local which is invalid since the client and server
    // clocks are always at least the tiniest bit misaligned
    foreach (SyncTableMetadata metaTable in groupMetadata.TablesMetadata)
    {
    SyncAnchor temp = metaTable.LastReceivedAnchor;
    metaTable.LastReceivedAnchor = metaTable.LastSentAnchor;
    metaTable.LastSentAnchor = temp;
    }

    // SyncTracer.Verbose("New Anchor: " + DeserializeAnchorValue(groupMetadata.NewAnchor.Anchor));

    SyncContext syncContext = _dbSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);

    // SyncTracer.Verbose("New Anchor: " + DeserializeAnchorValue(groupMetadata.NewAnchor.Anchor));

    //swap them back for consistency
    foreach (SyncTableMetadata metaTable in groupMetadata.TablesMetadata)
    {
    SyncAnchor temp = metaTable.LastReceivedAnchor;
    metaTable.LastReceivedAnchor = metaTable.LastSentAnchor;
    metaTable.LastSentAnchor = temp;
    }

    foreach (SyncTableMetadata table in groupMetadata.TablesMetadata)
    {
    SetTableReceivedAnchor(table.TableName, groupMetadata.NewAnchor);
    }

    return syncContext;

    }
    when i changed the applychanges to be like the previous code nothing work and the apllication gives me an error mesage that:
    table name 'INVL.MTL_SECONDARY_INVENTORIES' is not valid .this might be caused by on or more of the following issues:
    unable to find a syncadapter for the specified synctable,the table name is null or empty,or the table name contains the keywords:
    SET,FMTONLY and OFF .(argumentException was unhandled)

Alle Antworten

  • Montag, 29. Juni 2009 18:02
     
     
    Hi there,

    Is this exception coming from your express provider or oracle provider?  In any case are you sure the proper sync adapter has been added to each provider for that particular table?

    -Jesse
    • Als Antwort markiert tamer_mo3az Dienstag, 30. Juni 2009 16:31
    • Tag als Antwort aufgehoben tamer_mo3az Dienstag, 30. Juni 2009 16:31
    •  
  • Montag, 29. Juni 2009 20:08
     
      Enthält Code
    1-The exception is coming from the sqlExpressSyncProvider.
    2-yes i am sure the proper sync adapter has been added to each provider.
    this is the SqlExpressSyncProvider code:
    //-------------------------------------------------------------------------- 
    //
    //  Copyright (c) Microsoft Corporation.  All rights reserved. 
    //
    //  File: SqlExpressClientSyncProvider.cs 
    //
    //  Description: Generic client synchronization provider.
    //
    //--------------------------------------------------------------------------
    using Microsoft.Synchronization.Data;
    using Microsoft.Synchronization.Data.Server;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Sql;
    using System.Data.SqlClient;
    using System.IO;
    using System.Text;
    
    namespace Microsoft.Samples.Synchronization.Data.SqlExpress
    {
        ///<summary>
        /// A generic client sync provider that can connect to SQL Express
        /// </summary>
        /// <remarks>    
        /// SqlExpressClientSyncProvider inherits from ClientSyncProvider, and it is a generic 
        /// implementation of ServerSyncProvider. SqlExpressClientSyncProvider uses the mechanisms
        /// of DbServerSyncProvider to connect to the client (ie using a DBConnection)
        /// </remarks>
        public class SqlExpressClientSyncProvider : ClientSyncProvider
        {
            // wraps a DbServerSyncProvider
            private DbServerSyncProvider _dbSyncProvider;
            private Guid _clientId;
    
            private int _refCntSession;
            private IDbTransaction _transaction;
    
            private const string GuidTableName = "guid";
            private const string AnchorTableName = "anchor";
    
            public event EventHandler<ApplyChangeFailedEventArgs> ApplyChangeFailed;
    
            /// <summary>
            /// Default constructor
            /// </summary>
            public SqlExpressClientSyncProvider()
            {
                _dbSyncProvider = new DbServerSyncProvider();
                _dbSyncProvider.ApplyingChanges += new EventHandler<ApplyingChangesEventArgs>(_dbSyncProvider_ApplyingChanges);
                _dbSyncProvider.ApplyChangeFailed += new EventHandler<ApplyChangeFailedEventArgs>(_dbSyncProvider_ApplyChangeFailed);
                _clientId = Guid.Empty;
                _refCntSession = 0;
                _transaction = null;
            }
    
            void _dbSyncProvider_ApplyChangeFailed(object sender, ApplyChangeFailedEventArgs e)
            {
                if (ApplyChangeFailed != null)
                {
                    ApplyChangeFailed(sender, e);
                }
            }
    
            /// <summary>
            ///  Roll ApplyChanges() modifications done by inner _dbSyncProvider 
            ///  into one transaction with anchor changes
            /// </summary>
            /// <param name="sender"> Event params </param>
            /// <param name="e"> Event params </param>
            void _dbSyncProvider_ApplyingChanges(object sender, ApplyingChangesEventArgs e)
            {
                if (_transaction != null)
                    e.Transaction = _transaction;
            }
    
            /// <summary>
            /// Apply changes downloaded from the server. 
            /// </summary>
            /// <remarks>
            /// Inner _dbSyncProvider will take care of applying changes to actual 
            /// data, but we need to take care of updating anchor metadata. 
            /// </remarks>
            /// <param name="groupMetadata"> Contains table metadata info </param>
            /// <param name="dataSet"> Contains changes to be applied </param>
            /// <param name="syncSession"> Current sync session </param>
            /// <returns> SyncContext object to Sync Agent </returns>
            /*
            public override SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession)
            {
                SyncContext syncContext = _dbSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
                foreach (SyncTableMetadata table in groupMetadata.TablesMetadata)
                {
                    SetTableReceivedAnchor(table.TableName, groupMetadata.NewAnchor);
                }
                return syncContext;
    
            }
            */
    
            public override SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession)
            {
                //Map SyncDirection from client POV to our internal server POV
    
                foreach (SyncTableMetadata tableMetadata in groupMetadata.TablesMetadata)
                {
                    if (tableMetadata.SyncDirection == SyncDirection.DownloadOnly || tableMetadata.SyncDirection == SyncDirection.Snapshot)
                    {
                        //This SyncDirection DownloadOnly/Snapshot is from a Client point of view. But our client is inturn a Server provider.   Hence switch this to UploadOnly
                        tableMetadata.SyncDirection = SyncDirection.UploadOnly;
                    }
    
                    else if (tableMetadata.SyncDirection == SyncDirection.UploadOnly)
                    {
                        //This SyncDirection UploadOnly is from Client POV. But our client is inturn a Server provider. Hence switch this to DownloadOnly
                        tableMetadata.SyncDirection = SyncDirection.DownloadOnly;
                    }
                }
    
                // neet to set the LastReceivedAnchor as the LastSentAnchor since 
                // DbServerSyncProvider operates from the server's perspective, so
                // we swap the two fields temporarily. 
                // Note that even if we do this, the NewAnchor value will be the one
                // from the server, not local which is invalid since the client and server
                // clocks are always at least the tiniest bit misaligned
                foreach (SyncTableMetadata metaTable in groupMetadata.TablesMetadata)
                {
                    SyncAnchor temp = metaTable.LastReceivedAnchor;
                    metaTable.LastReceivedAnchor = metaTable.LastSentAnchor;
                    metaTable.LastSentAnchor = temp;
                }
    
                // SyncTracer.Verbose("New Anchor: " + DeserializeAnchorValue(groupMetadata.NewAnchor.Anchor));
    
                SyncContext syncContext = _dbSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
    
                // SyncTracer.Verbose("New Anchor: " + DeserializeAnchorValue(groupMetadata.NewAnchor.Anchor));
    
                //swap them back for consistency
                foreach (SyncTableMetadata metaTable in groupMetadata.TablesMetadata)
                {
                    SyncAnchor temp = metaTable.LastReceivedAnchor;
                    metaTable.LastReceivedAnchor = metaTable.LastSentAnchor;
                    metaTable.LastSentAnchor = temp;
                }
    
                foreach (SyncTableMetadata table in groupMetadata.TablesMetadata)
                {
                    SetTableReceivedAnchor(table.TableName, groupMetadata.NewAnchor);
                }
    
                return syncContext;
    
            }
    
    
            /// <summary>
            /// Creates the database schema on client database -- NOT IMPLEMENTED
            /// </summary>
            /// <remarks>
            /// In the current implementation of this class, we assume that the 
            /// client already has the same schema as the server (run the demo scripts).
            /// </remarks>
            public override void CreateSchema(SyncTable syncTable, SyncSchema syncSchema)
            {
                //throw new NotSupportedException("Create Schema is not supported in this version."
                //        + "Please make sure client and server have same schema!");
    
            }
    
    
            /// <summary>
            /// Gets the changes made on the client since last sync.
            /// </summary>
            /// <param name="groupMetadata"> Contains table metadata </param>
            /// <param name="syncSession"> The current sync session </param>
            /// <returns> SyncContext populated with the incremental changes </returns>
            public override SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession)
            {
                // neet to set the LastReceivedAnchor as the LastSentAnchor since 
                // DbServerSyncProvider operates from the server's perspective, so
                // we swap the two fields temporarily. 
                foreach (SyncTableMetadata metaTable in groupMetadata.TablesMetadata)
                {
                    SyncAnchor temp = metaTable.LastReceivedAnchor;
                    metaTable.LastReceivedAnchor = metaTable.LastSentAnchor;
                    metaTable.LastSentAnchor = temp;
                }
    
                SyncContext context = _dbSyncProvider.GetChanges(groupMetadata, syncSession);
    
                //swap them back for consistency
                foreach (SyncTableMetadata metaTable in groupMetadata.TablesMetadata)
                {
                    SyncAnchor temp = metaTable.LastReceivedAnchor;
                    metaTable.LastReceivedAnchor = metaTable.LastSentAnchor;
                    metaTable.LastSentAnchor = temp;
                }
                return context;
            }
    
            /// <summary>
            /// Gets the client's ID
            /// </summary>
            /// <remarks>
            /// This function currently just reads the value in a database table
            /// named 'guid,' which is initialized upon client database creation
            /// (see demo script). 
            /// </remarks>
            /// <returns> A Guid object containing client's ID </returns>
            public Guid GetClientId()
            {
                if (_clientId == Guid.Empty)
                {
                    IDbCommand guidCom = null;
                    IDataReader reader = null;
                    try
                    {
                        BeginTransaction(null);
                        string queryStr = "SELECT Guid FROM " + GuidTableName;
                        guidCom = new SqlCommand(queryStr);
                        guidCom.Connection = _dbSyncProvider.Connection;
                        guidCom.CommandType = CommandType.Text;
                        guidCom.Transaction = _transaction;
                        reader = guidCom.ExecuteReader();
                        if (reader.Read())
                        {
                            _clientId = reader.GetGuid(0);
                        }
                    }
                    catch
                    {
                        _clientId = Guid.Empty;
                        throw;
                    }
                    finally
                    {
                        if (reader != null && !reader.IsClosed)
                            reader.Close();
                        reader.Dispose();
                        guidCom.Dispose();
                        EndTransaction(true, null);
                    }
    
                }
                return _clientId;
            }
    
            /// <summary>
            /// Retrieves the last received anchor from the 'anchor' metatable.
            /// </summary>
            /// <param name="tableName"> The name of the table which we want the anchor for. </param>
            /// <returns> A sync anchor object containing the last received anchor. </returns>
            public override SyncAnchor GetTableReceivedAnchor(string tableName)
            {
                string queryStr = "SELECT ReceivedAnchor FROM " + AnchorTableName + " WHERE TableName = '" + tableName + "'";
                IDbCommand receivedAnchorCom = new SqlCommand(queryStr);
                receivedAnchorCom.Connection = _dbSyncProvider.Connection;
                receivedAnchorCom.CommandType = CommandType.Text;
                receivedAnchorCom.Transaction = _transaction;
    
                object anchorVal = null;
                bool commandPassed = false;
                try
                {
                    BeginTransaction(null);
                    anchorVal = receivedAnchorCom.ExecuteScalar();
                    commandPassed = true;
                }
                finally
                {
                    receivedAnchorCom.Dispose();
                    EndTransaction(commandPassed, null);
                }
    
                if (anchorVal == null || anchorVal == System.DBNull.Value)
                    return new SyncAnchor();
                else
                    return new SyncAnchor((byte[])anchorVal);
            }
    
            /// <summary>
            /// Retrieves the last sent anchor from the 'anchor' metatable.
            /// </summary>
            /// <param name="tableName"> The name of the table for which we want the anchor. </param>
            /// <returns> A sync anchor object containing the last sent anchor. </returns>
            public override SyncAnchor GetTableSentAnchor(string tableName)
            {
                string queryStr = "SELECT SentAnchor FROM " + AnchorTableName + " WHERE TableName = '" + tableName + "'";
                IDbCommand sentAnchorCom = new SqlCommand(queryStr);
                sentAnchorCom.Connection = _dbSyncProvider.Connection;
                sentAnchorCom.CommandType = CommandType.Text;
                sentAnchorCom.Transaction = _transaction;
                object anchorVal = null;
                bool commandPassed = false;
                try
                {
                    BeginTransaction(null);
                    anchorVal = sentAnchorCom.ExecuteScalar();
                    commandPassed = true;
                }
                finally
                {
                    sentAnchorCom.Dispose();
                    EndTransaction(commandPassed, null);
                }
    
                if (anchorVal == System.DBNull.Value)
                    return new SyncAnchor();
                else
                    return new SyncAnchor((byte[])anchorVal);
            }
    
            /// <summary>
            /// Sets the last received anchor in the 'anchor' metatable
            /// </summary>
            /// <param name="tableName"> The name of the table for which we want to set the anchor </param>
            /// <param name="anchor"> SyncAnchor object containing the anchor. </param>
            public override void SetTableReceivedAnchor(string tableName, SyncAnchor anchor)
            {
                string queryStr = "UPDATE " + AnchorTableName +
                    " SET ReceivedAnchor = @anchor WHERE TableName = '" + tableName + "'";
                SqlCommand anchorCom = new SqlCommand(queryStr);
                anchorCom.Parameters.AddWithValue("@anchor", anchor.Anchor);
                anchorCom.Connection = (SqlConnection)_dbSyncProvider.Connection;
                anchorCom.Transaction = (SqlTransaction)_transaction;
                bool commandPassed = false;
                try
                {
                    BeginTransaction(null);
                    if (anchorCom.ExecuteNonQuery() == 0)
                        throw new Exception("SetTableReceivedAnchor() had no effect");
                    commandPassed = true;
                }
                finally
                {
                    anchorCom.Dispose();
                    EndTransaction(commandPassed, null);
                }
            }
    
            /// <summary>
            /// Sets teh last sent anchor in the 'anchor' metatable
            /// </summary>
            /// <param name="tableName"> The name of the table for whcih we want to set the anchor </param>
            /// <param name="anchor"> SyncAnchor object containing the anchor. </param>
            public override void SetTableSentAnchor(string tableName, SyncAnchor anchor)
            {
                string queryStr = "UPDATE " + AnchorTableName +
                    " SET SentAnchor = @anchor WHERE TableName = '" + tableName + "'";
                SqlCommand anchorCom = new SqlCommand(queryStr);
                anchorCom.Parameters.AddWithValue("@anchor", anchor.Anchor);
                anchorCom.Connection = (SqlConnection)_dbSyncProvider.Connection;
                anchorCom.Transaction = (SqlTransaction)_transaction;
    
                bool commandPassed = false;
                try
                {
                    BeginTransaction(null);
                    if (anchorCom.ExecuteNonQuery() == 0)
                        throw new Exception("SetTableSentAnchor() had no effect");
                    commandPassed = true;
                }
                finally
                {
                    anchorCom.Dispose();
                    EndTransaction(commandPassed, null);
                }
            }
    
            /// <summary>
            /// Begin a transaction. This method is invoked to mark atomic operations.   
            /// </summary>
            /// <param name="syncSession">SyncSession information</param>               
            public override void BeginTransaction(SyncSession syncSession)
            {
                _refCntSession++;
                if (Connection.State == ConnectionState.Closed)
                {
                    Connection.Open();
                }
                if (_transaction == null)
                {
                    _transaction = _dbSyncProvider.Connection.BeginTransaction();
                }
            }
    
            /// <summary>
            /// End transaction. This method is called by the agent at to conclude an atomic operation.
            /// </summary>
            /// <param name="commit">Commit/Abort SyncSession</param>               
            /// <param name="syncSession">SyncSession information</param>               
            public override void EndTransaction(bool commit, SyncSession syncSession)
            {
                _refCntSession--;
                if (_refCntSession == 0)
                {
                    if (commit)
                        _transaction.Commit();
                    else
                        _transaction.Rollback();
    
                    _transaction.Dispose();
                    _transaction = null;
    
                    Connection.Close();
                }
                if (_refCntSession < 0) _refCntSession = 0;
                //else if (_refCntSession < 0)
                //    throw new SyncException("Transaction error: _refCntSession < 0");
            }
            /// <summary>
            /// Disposes this Client Sync Provider instance 
            /// </summary>
            public override void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            /// <summary>
            /// Disposes this Client Sync Provider instance 
            /// </summary>
            /// <param name="disposing">True if explicit finalization, false if through GC</param>
            //[SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive")]
            protected virtual void Dispose(bool disposing)
            {
                _dbSyncProvider.Dispose();
            }
    
            #region public properties
    
            /// <summary>
            /// Gets or sets the command that will return the new anchor value. 
            /// </summary>
            /// <value>
            /// A <b>IDbCommand</b>-inheritated object.
            /// </value>
            public IDbCommand SelectNewAnchorCommand
            {
                get
                {
                    return _dbSyncProvider.SelectNewAnchorCommand;
                }
                set
                {
                    _dbSyncProvider.SelectNewAnchorCommand = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the server connection object.
            /// </summary>
            /// <value>
            /// A <b>DbConnection</b> object.
            /// </value>
            public IDbConnection Connection
            {
                get
                {
                    return _dbSyncProvider.Connection;
                }
                set
                {
                    if (value == null)
                    {
                        throw new ArgumentNullException("value");
                    }
    
                    if (value.State == ConnectionState.Closed)
                    {
                        // giving the connection to the _dbSyncPRovider as open 
                        // will prevent it from closing off the connection at end 
                        // of operations
                        value.Open();
                        _dbSyncProvider.Connection = value;
                        value.Close();
                    }
                    else _dbSyncProvider.Connection = value;
    
                }
            }
    
            /// <summary>
            /// Gets the collection of <b>SyncAdapter</b>.
            /// </summary>
            /// <value>
            /// A <b>SyncAdapterCollection</b> object.
            /// </value>
            public SyncAdapterCollection SyncAdapters
            {
                get
                {
                    return _dbSyncProvider.SyncAdapters;
                }
            }
    
    
            /// <summary>
            /// Gets and sets ClientId
            /// </summary>
            /// <remarks>
            /// A new client is generated and saved if none is present
            /// </remarks>
            /// <value>
            /// A <b>Guid</b> object.
            /// </value>
            public override Guid ClientId
            {
                get
                {
                    return GetClientId();
                }
    
                set
                {
                    _clientId = value;
                }
            }
            #endregion
        }
    }
    
    i think the problem may come from the following:
    since i am using oracle as the backend i have to create the schema myself,and this part is not implemented in the custom sqlExpressSyncProvider:
    so i think the solution may come from implemnting this function
     public override void CreateSchema(SyncTable syncTable, SyncSchema syncSchema)
    {
    //throw new NotSupportedException("Create Schema is not supported in this version."
    // + "Please make sure client and server have same schema!");

    }

    also i would like to figure out that i call the create schema function from my DbServerSyncProvider inherited class:
    me.schema=me.createSchema
    Private Function CreateSchema() As SyncSchema
            Dim syncScema As New SyncSchema
    
            'the store organization table
    
            syncScema.Tables.Add("INV.MTL_SECONDARY_INVENTORIES")
    
            'ORGANIZATION_ID column
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns.Add("ORGANIZATION_ID")
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("ORGANIZATION_ID").AllowNull = False
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("ORGANIZATION_ID").ProviderDataType = "NUMERIC"
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("ORGANIZATION_ID").NumericPrecision = 10
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("ORGANIZATION_ID").NumericScale = 0
    
            'SECONDARY_INVENTORY_NAME column
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns.Add("SECONDARY_INVENTORY_NAME")
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("SECONDARY_INVENTORY_NAME").AllowNull = False
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("SECONDARY_INVENTORY_NAME").ProviderDataType = "CHAR"
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").Columns("SECONDARY_INVENTORY_NAME").MaxLength = 10
    
            syncScema.Tables("INV.MTL_SECONDARY_INVENTORIES").PrimaryKey = New String() {"ORGANIZATION_ID", "SECONDARY_INVENTORY_NAME"}
    Return syncScema
    
        End Function


    Thank you very much for your fast reply and your concern,
    really this issue postpones my work very much
  • Mittwoch, 1. Juli 2009 19:20
     
     
    Hmm...are you starting with the schema created on both sides before the sync?  Is "INV.MTL_SECONDARY_INVENTORIES" a valid oracle name? (Can't remember if oracle likes the "INV." part).  Although you say this is exception is coming from the Sql Express provider...Have you tried your SQL Express Provider working with the SQL Server provider (I realize this might not be possible, but it might help narrow down the problem to oracle related stuff).

    -Jesse
  • Samstag, 4. Juli 2009 19:21
     
     
    Hi mr.Jesse,
    1-I can't start with the same schema on both sides,because in case of syncronizing with oracle,you have to create the schema on the client yourself,,since i am using an oracle database as the back end, the schema information retrieved from the Oracle server database is not enough for SqlExpressto create the tables .
    2-Second if use the same code,but inheriting my clientsyncprovider from sqlceclientSyncProvider,everything is working properly.
    Thanks
  • Dienstag, 7. Juli 2009 00:00
     
     
    Hi,

    Sorry for the delay.  You should be creating the schema on your client db before sync with a script.  If you look at the sample, that is what it is doing in the CreateDatabase_Local script.  These scripts also populate the anchors which you also should be doing.  This is easier than implementing CreateSchema.  Let me know if this works.

    -Jesse
  • Dienstag, 7. Juli 2009 15:38
     
      Enthält Code
    Hi mr.Jesse,
    I created the same schema on the client(sql server 2005 express) and the result was the following exception:
    invalid operation exception:
    message:Syntax Error: Expecting identifier or quoted identifier.
    stack trace:stack trace:"at System.Data.OracleClient.DbSqlParser.Parse2(String statementText)    at System.Data.OracleClient.OracleDataReader.FillSchemaTable(DataTable schemaTable)    at System.Data.OracleClient.OracleDataReader.GetSchemaTable()    at System.Data.ProviderBase.SchemaMapping..ctor(DataAdapter adapter, DataSet dataset, DataTable datatable, DataReaderContainer dataReader, Boolean keyInfo, SchemaType schemaType, String sourceTableName, Boolean gettingData, DataColumn parentChapterColumn, Object parentChapterValue)    at System.Data.Common.DataAdapter.FillSchemaFromReader(DataSet dataset, DataTable datatable, SchemaType schemaType, String srcTable, IDataReader dataReader)    at System.Data.Common.DataAdapter.FillSchema(DataTable dataTable, SchemaType schemaType, IDataReader dataReader)    at System.Data.Common.DbDataAdapter.FillSchemaInternal(DataSet dataset, DataTable datatable, SchemaType schemaType, IDbCommand command, String srcTable, CommandBehavior behavior)    at System.Data.Common.DbDataAdapter.FillSchema(DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior)    at System.Data.Common.DbDataAdapter.FillSchema(DataTable dataTable, SchemaType schemaType)    at Microsoft.Synchronization.Data.Server.SyncAdapter.FillSchema(DataTable dataTable, IDbConnection connection)    at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.GetSchemaFromDatabase(Collection`1 tableNames, Collection`1& missingTables, Exception& exp)    at Microsoft.Synchronization.Data.Server.DbServerSyncProvider.GetSchema(Collection`1 tableNames, SyncSession syncSession)    at Microsoft.Synchronization.SyncAgent.InitClientSchema()    at Microsoft.Synchronization.SyncAgent.Synchronize()    at OracleToSqlExpressSyncFramework.Form1.btnSynchronize_Click(Object sender, EventArgs e) in D:\projects\OracleToSqlExpressSyncFramework\OracleToSqlExpressSyncFramework\Form1.vb:line 28    at System.Windows.Forms.Control.OnClick(EventArgs e)    at System.Windows.Forms.Button.OnClick(EventArgs e)    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)    at System.Windows.Forms.Control.WndProc(Message& m)    at System.Windows.Forms.ButtonBase.WndProc(Message& m)    at System.Windows.Forms.Button.WndProc(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)    at System.Windows.Forms.Application.Run(ApplicationContext context)    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()    at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)    at OracleToSqlExpressSyncFramework.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81    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()"

    also this is the script of the sql server express CREATE TABLE [dbo].[INV.MTL_SECONDARY_INVENTORIES]( [ORGANIZATION_ID] [numeric](18, 0) NOT NULL, [SECONDARY_INVENTORY_NAME] [varchar](10) COLLATE Arabic_CI_AS NOT NULL, PRIMARY KEY CLUSTERED ( [ORGANIZATION_ID] ASC, [SECONDARY_INVENTORY_NAME] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] also,this is the script of the oracle table: CREATE TABLE MTL_SECONDARY_INVENTORIES ( SECONDARY_INVENTORY_NAME VARCHAR2(10 BYTE) NOT NULL, ORGANIZATION_ID NUMBER NOT NULL )
    • Bearbeitet tamer_mo3az Mittwoch, 8. Juli 2009 13:47
    •