Dotmim.Sync is throwing exception when synchronizing existing SQLite with SQL Server databases - sql-server

I get a Dotmim.Sync.SyncException when calling the agent.SynchronizeAsync(tables) function:
Exception: Seems you are trying another Setup tables that what is stored in your server scope database. Please make a migration or create a new scope
This is my code:
public static async Task SynchronizeAsync()
{
var serverProvider = new SqlSyncProvider(serverConnectionString);
// Second provider is using plain old Sql Server provider, relying on triggers and tracking tables to create the sync environment
var clientProvider = new SqliteSyncProvider(Path.Combine(FileSystem.AppDataDirectory, "treesDB.db3"));
// Tables involved in the sync process:
var tables = new string[] { "Trees" };
// Creating an agent that will handle all the process
var agent = new SyncAgent(clientProvider, serverProvider);
// Launch the sync process
var s1 = await agent.SynchronizeAsync(tables);
await agent.LocalOrchestrator.UpdateUntrackedRowsAsync();
var s2 = await agent.SynchronizeAsync();
}

I'm the author of Dotmim.Sync
Do not hesitate to to fill an issue on Github if you are still struggling.
Regarding your issue, I think you have made some tests with different tables.
You need to stick with a set of tables, because DMS needs to create different things (triggers / stored proc and so on)
If you want to test different setups, you need to define differents scopes.
You have a complete documentation on https://dotmimsync.readthedocs.io/

Related

How would I configure Effort Testing Tool to mock Entity Framework's DbContext withOut the actual SQL Server Database up and running?

Our team's application development involves using Effort Testing Tool to mock our Entity Framework's DbContext. However, it seems that Effort Testing Tool needs to be see the actual SQL Server Database that the application uses in order to mock our Entity Framework's DbContext which seems to going against proper Unit Testing principles.
The reason being that in order to unit test our application code by mocking anything related to Database connectivity ( for example Entity Framework's DbContext), we should Never need a Database to be up and running.
How would I configure Effort Testing Tool to mock Entity Framework's DbContext withOut the actual SQL Server Database up and running?
*
Update:
#gert-arnold We are using Entity Framework Model First approach to implement the back-end model and database.
The following excerpt is from the test code:
connection = Effort.EntityConnectionFactory.CreateTransient("name=NorthwindModel");
jsAudtMppngPrvdr = new BlahBlahAuditMappingProvider();
fctry = new BlahBlahDataContext(jsAudtMppngPrvdr, connection, false);
qryCtxt = new BlahBlahDataContext(connection, false);
audtCtxt = new BlahBlahAuditContext(connection, false);
mockedReptryCtxt = new BlahBlahDataContext(connection, false);
_repository = fctry.CreateRepository<Account>(mockedReptryCtxt, null);
_repositoryAccountRoleMaps = fctry.CreateRepository<AccountRoleMap>(null, _repository);
The "name=NorthwindModel" pertains to our edmx file which contains information about our Database tables
and their corresponding relationships.
If I remove the "name=NorthwindModel" by making the connection like the following line of code, I get an error stating that it expects an argument:
connection = Effort.EntityConnectionFactory.CreateTransient(); // throws error
Could you please explain how the aforementioned code should be rewritten?
You only need that connection string because Effort needs to know where the EDMX file is.
The EDMX file contains all information required for creating an inmemory store with an identical schema you have in your database. You have to specify a connection string only because I thought it would be convenient if the user didn't have to mess with EDMX paths.
If you check the implementation of the CreateTransient method you will see that it merely uses the connection string to get the metadata part of it.
public static EntityConnection CreateTransient(string entityConnectionString, IDataLoader dataLoader)
{
var metadata = GetEffortCompatibleMetadataWorkspace(ref entityConnectionString);
var connection = DbConnectionFactory.CreateTransient(dataLoader);
return CreateEntityConnection(metadata, connection);
}
private static MetadataWorkspace GetEffortCompatibleMetadataWorkspace(ref string entityConnectionString)
{
entityConnectionString = GetFullEntityConnectionString(entityConnectionString);
var connectionStringBuilder = new EntityConnectionStringBuilder(entityConnectionString);
return MetadataWorkspaceStore.GetMetadataWorkspace(
connectionStringBuilder.Metadata,
metadata => MetadataWorkspaceHelper.Rewrite(
metadata,
EffortProviderConfiguration.ProviderInvariantName,
EffortProviderManifestTokens.Version1));
}

Return multiple tables in one SQL Connection using Entity Framework

When i use Entity Framework Profiler the following code makes 3 calls to the database.
using (var entities = new Entities())
{
var faqs = entities.Table1.ToList();
var latest = entities.Table2.ToList();
var inst = entities.Table3.ToList();
}
I would like to make one database call, is there anyway to do this without calling a stored procedure?
I am trying to eliminate database calls throughout my application.
You can do a cross join in ef,
See this
http://geekswithblogs.net/berthin/archive/2012/05/25/how-to-perform-cross-join.aspx
My problem was solved by using the nuget package EntityFramework.Extended.
So using my original code, this is how you would solve my issue.
using (var entities = new Entities())
{
var faqs = entities.Table1.Future();
var latest = entities.Table2.Future();
var inst = entities.Table3.Future();
inst.ToList();
}
When you call ToList() a batch call is sent to your database in one connection.
The reference link is below:
https://github.com/loresoft/EntityFramework.Extended/wiki/Future-Queries

Issue with getting database via Sitecore API

We noticed a slight oddity in the Sitecore API code. The code is below for your reference. The code is trying to get a database by doing new Database(database). But randomly it was failing.
This code worked for a while with Database db = new Database(database); but started failing randomly yesterday. When we changed the code to Database db = Database.GetDatabase(database);, the code started working again. What is the difference between the two approaches and what is recommended by Sitecore?
I've seen this happen twice now - multiple times in production and a couple of times in my development environment.
public static void DeleteItem(string id, stringdatabase)
{
//get the database
Database db = new Database(database);
//get the item
item = db.GetItem(new ID(id));
if (item != null)
{
using(new Sitecore.SecurityModel.SecurityDisabler())|
{
//delete the item
item.Delete();
}
}
}
A common way you will see people get a specific database is:
Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
This is equivalent to Sitecore.Data.Database.GetDatabase("master").
When you call either of these methods it will first check the cache for the database. If not found it will build up the database with all of the configuration values within the config file via reflection. Once the database is created it will be placed in the cache for future use.
When you use the constructor on the database it is simply creating a rather empty database object. I am rather suprised to hear it was working at all when you used this method.
The proper approach to get a specific database would be to use:
Sitecore.Configuration.Factory.GetDatabase("master");
// or
Sitecore.Data.Database.GetDatabase("master");
If you are looking to get the database used with the current request (aka context database) you can use Sitecore.Context.Database. You can also use Sitecore.Context.ContentDatabase.

Setting only the ID in a Linq to SQL object

I am using Linq to SQL in a two tier project where the server tier abstracts the DB and is using Linq to SQL.
In my client tier I construct an object and I send to the server.
I have a Task, which has a relationship to Reporter (who reported this task), so Task has a ReportedID column in the database, which is a FK to Reporter.ID.
In the Linq abstraction, my Task has a Reporter property and a ReportedID property.
To save new Tasks, I would like to use the ReportedID, so I have this code:
//Populate the object with the info
Task task = new Task();
task.Title = tbTitle.Text;
task.Description = tbDescription.Text;
task.Severity = ((Severity)lbSeverities.SelectedItem);
//the first state: "open"
task.StateID = 1;
//TODO - Set ReporterID
task.ReporterID = 1;
//Save the task
client.SaveTaskCompleted += new EventHandler<SaveTaskCompletedEventArgs>(client_SaveTaskCompleted);
client.SaveTaskAsync(App.Token, task);
So, the object is constructed and sent to the server, where it is saved using this code:
public Task SaveTask(string token, Task task)
{
TrackingDataContext dataConext = new TrackingDataContext();
//Saves/Updates the task
dataConext.Tasks.InsertOnSubmit(task);
dataConext.SubmitChanges();
return task;
}
The problem is that I get an exception: "An attempt was made to remove a relationship between a Reporter and a Task. However, one of the relationship's foreign keys (Task.ReporterID) cannot be set to null.".
If I use the Reporter property, it works.
What am I doing wrong?
Thank you,
Oscar
I made some refactory in my code and this error doesn't anymore. It may be a logic error but I can't tell exactly what.

SQL Reporting Services DataConnection Update

Is it possible to change the connection string of a published sql reporting services report? I can see the binary field called DataSource in the ReportServer database, but since it's stored as binary I don't think it's easily updatable.
Do I need to republish the report with the correct data source? I'm hoping not since I do not want to have to install VS2003.
EDIT: The client is running SQL Server 2000 Reporting Services with all of the service packs installed.
SQL Reporting Services 2000 has a [web service](http://msdn.microsoft.com/en-us/library/aa274396(SQL.80).aspx) that you can use to change the data source. Given that, the following, allows for changing of a data source to a shared data source. This was [adapted from MSDN](http://msdn.microsoft.com/en-us/library/aa225896(SQL.80).aspx).
// Create our reporting services class
ReportingService theRS = new ReportingService();
theRS.Credentials = System.Net.CredentialCache.DefaultCredentials;
// We need to setup a data source reference to an existing shared data source
DataSourceReference theDSRef = new DataSourceReference();
theDSRef.Reference = "/Path/To/ExistingSharedDataSource";
DataSource[] theDSArray = new DataSource[1];
DataSource theDS = new DataSource();
theDS.Item = (DataSourceReference)theDSRef;
theDS.Name = "NameOfSharedDataSource";
theDSArray[0] = theDS;
try
{
// Attempt to change the data source of the report
theRS.SetReportDataSources("/Path/To/ReportName", theDSArray);
Console.Out.WriteLine("We have changed the data source");
}
catch (System.Web.Services.Protocols.SoapException e)
{
Console.Out.WriteLine(e.Message);
Console.Out.WriteLine(e.Detail.InnerXml.ToString());
}
In this example, the ReportingService class is taken from the Proxy class that I generated to talk to the web service, which is described [here](http://msdn.microsoft.com/en-us/library/aa256607(SQL.80).aspx).
I hope this helps some. Let me know if you're looking for something different.

Resources