I have implemented a small Windows Service which runs every 9 minutes and writes the data which comes througth a webservice to the db.
Do do the db work I use Linq To SQL
using (var db = new DataClasses1DataContext())
{
var currentWeather = this.GetWeatherData();
//////TODO Add the data correct
var newEntry = new WeatherData()
{
test = currentWeather.dateGenerated.ToShortTimeString()
};
//var test = db.WeatherDatas.First();
db.WeatherDatas.InsertOnSubmit(newEntry); // this throws Invalid Operation Exception
db.SubmitChanges();
}
Why does it throw this exception? the same codeblock in a console programm runs nice
alt text http://img687.imageshack.us/img687/7588/unbenanntxb.png
Have you set up the connection string in app.Config correctly?
IIRC, the default constructor on an L2S DataContext reads the connection string from the config file. If the connection string points to the the wrong database (or one that doesn't exist) you may very well receive an exception.
This could also explain why this piece of code works when executed in a different context.
Related
I Have a database that we want to partially sync data out of into another database (on Azure).
I have been looking at Sync Framework 2.1 and believe it can solve the problem, however i cannot figure it out from the online documentation.
We have the restraint that we cannot change the schema of the database however we are on SQL 2008 R2 which means that we can use track changes.
I am looking for some advise on how this might be achieved.
currently i have a SyncOrchestrator
var orch = new SyncOrchestrator
{
LocalProvider = new SampleServerSyncProvider(),
RemoteProvider = new SampleClientSymcProvider(),
Direction = SyncDirectionOrder.Upload
};
and then a sync provider
public class SampleServerSyncProvider : DbServerSyncProvider
{
private String SQLLocalConnection = "valid connection string";
public SampleServerSyncProvider()
{
SqlConnection serverConn = new SqlConnection(SQLLocalConnection);
Connection = serverConn;
Connection.Open();
var cmTableSyncAdapter = new SqlSyncAdapterBuilder
{
Connection = serverConn,
ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking,
SyncDirection = SyncDirection.Bidirectional,
TableName = "my table"
};
SyncAdapters.Add(cmTableSyncAdapter.ToSyncAdapter());
}
}
Currently i am getting an error that talks about initializing the connection. But I cannot find an initialize method on any of the objects
System.InvalidOperationException : Cannot create a SyncAdapter for table 'My table' by using
SqlSyncAdapterBuilder because the connection to the server has not yet
been initialized. Initialize the Connection property of the
SqlSyncAdapterBuilder before you call any of the SqlSyncAdapterBuilder
methods
SQL Change Tracking is only supported on the older offline providers (SqlClientSyncProvider/DbServerSyncProvider/SyncAgent). The newer providers you're trying to use (SqlSyncProvider/SyncOrchestrator) requires a custom change tracking. You cannot mix and match the database sync providers.
have you looked at using SSIS instead?
In my WCF service, I try to load a File from MS SQL table which has a FileStream column and I try to pass it as a stream back
responseMsg.DocSqlFileStream = new MemoryStream();
try
{
using (FileStreamDBEntities dbEntity = new FileStreamDBEntities())
{
...
using (TransactionScope x = new TransactionScope())
{
string sqlCmdStr = "SELECT dcraDocFile.PathName() AS InternalPath, GET_FILESTREAM_TRANSACTION_CONTEXT() AS TransactionContext FROM dcraDocument WHERE dcraDocFileID={0}";
var docFileStreamInfo = dbEntity.Database.SqlQuery<DocFileStreamPath>(sqlCmdStr, new object[] { docEntity.dcraDocFileID.ToString() }).First();
SqlFileStream sqlFS = new SqlFileStream(docFileStreamInfo.InternalPath, docFileStreamInfo.TransactionContext, FileAccess.Read);
sqlFS.CopyTo(responseMsg.DocSqlFileStream);
if( responseMsg.DocSqlFileStream.Length > 0 )
responseMsg.DocSqlFileStream.Position = 0;
x.Complete();
}
}
...
I'm wondering whats the best way to pass the SQLFileStream back through a message contract back to take advantage of streaming. Currently I copied the SQLFilEStream to a memory stream because I got an error message in WCF trace which says: Type 'System.Data.SqlTypes.SqlFileStream' cannot be serialized.
In WebApi there is such thing as PushStreamContent it allows delegating all transaction stuff to async lambda, don't know if there is something similar in WCF, but the following approach may be helpful:
http://weblogs.asp.net/andresv/archive/2012/12/12/asynchronous-streaming-in-asp-net-webapi.aspx
You can't stream an SQLFileStream back to the client because it can only be read within the SQL transaction. I think your solution with the MemoryStream is a good way of dealing with the problem.
I had a similar problem and was worried about the large object heap when using a new Memory Stream every time. I came up with the idea of using a temporary file on the disk instead of a memory stream. We are using this solution in several project now and it works really well.
See here for the example code:
https://stackoverflow.com/a/11307324/173711
I'm using autofac and the interfaces are correctly resolved but this code fails with "No connection could be made because the target machine actively refused it 127.0.0.1:8081"
using (var store = GetService<IDocumentStore>())
{
using (var session = store.OpenSession())
{
session.Store(new Entry { Author = "bob", Comment = "My son says this", EntryId = Guid.NewGuid(), EntryTime = DateTime.Now, Quote = "I hate you dad." });
session.SaveChanges();
}
}
Here is the registration
builder.Register<IDocumentStore>(c =>
{
var store = new DocumentStore { Url = "http://localhost:8081" };
store.Initialize();
return store;
}).SingleInstance();
When I navigate to http://localhost:8081 I do get the silverlight management UI. Although I'm running a Windows VM and vmware and Silverlight5 don't play together. That's another issue entirely. Anyways does anyone see what I'm doing wrong here or what I should be doing differently? Thanks for any code, tips, or tricks.
On a side note, can I enter some dummy records from a command line interface? Any docs or examples of how I can do that?
Thanks All.
Just curious, are you switching RavenDB to listen on 8081? The default is 8080. If you're getting the management studio to come up, I suspect you are.
I'm not too familiar with autofac but, it looks like you're wrapping your singleton DocumentStore in a using statement.
Try:
using (var session = GetService<IDocumentStore>().OpenSession())
{
}
As far as dummy records go, the management studio will ask you if you want to generate some dummy data if your DB is empty. If you can't get silverlight to work in the VM, I'm not sure if there's another automated way to do it.
Perhaps using smuggler:
http://ravendb.net/docs/server/administration/export-import
But you'd have to find something to import.
i am trying to setup Redis on appharbor. I have followed their instructions and again i have an issue with the Booksleeve API. Here is the code i am using to make it work initially:
var connectionUri = new Uri(url);
using (var redis = new RedisConnection(connectionUri.Host, connectionUri.Port, password: connectionUri.UserInfo.Split(new[] { ':' }, 2)[1]))
{
redis.Strings.Set(1, "greeting", "welcome to remember your stuff!");
try
{
var task = redis.Strings.GetString(1, "greeting");
redis.Wait(task);
ViewBag.Message = task.Result;
}
catch (Exception)
{
// It throws an exception trying to wait for the task?
}
}
However, the issue is that it sets the string correctly, but when trying to retrieve the same string from the key value store, it throws a timeout exception waiting for the task to eexecute. However, this code works on my local redis server connection.
Am i using the API in a wrong way? or is this something related to Appharbor?
Thanks
Like a SqlConnection, you need to call Open() (otherwise your messages are queued for delivery).
Unlike SqlConnection, you should not fire up a RedisConnection each time you need it - it is intended to be used as a shared, thread-safe, multiplexer - i.e. a single connection is held somewhere and used by lots and lots of unrelated callers. Unless of course you only need to do one thing!
I have an ODATA services with a single schema. These point to a development database, and is served through a WCF Data Service which is then used by clients running Excel/Powerpivot to fetch their own data for reports and such.
The service is secured at runtime through pretty much the same basic authentication explained here: http://msdn.microsoft.com/en-us/data/gg192997
Now how this needs to work in the live environment is sit on the server and connect to different databases based on the username/password supplied. the Users will be typing in 'username#clientID' and 'password'. 'username#clientID' is then split() and username/password is checked against the SQL database. But the database server URL to check against will be determined by ClientID.
Also, once it is authorized the WCF data service needs to return data from the Database corresponding to the ClientID.
The approach I tried was to modify the connection string in the web.config file, but this doesn't work because it says the file is read-only. I'm not even sure if this would have worked at all. What I need to do is get the EDMX/WCF Data service to return the data from the correct database. Here's what I tried to do:
private static bool TryAuthenticate(string user, string password, out IPrincipal principal)
{
Configuration myWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
myWebConfig.AppSettings.Settings["test"].Value = "Hello";
myWebConfig.Save();
string newConnStr = myWebConfig.ConnectionStrings.ConnectionStrings["IntelCorpEntities"].ToString();
newConnStr.ToString().Replace("SERGEIX01", "SERVERX01");
myWebConfig.ConnectionStrings.ConnectionStrings["IntelCorpEntities"].ConnectionString = newConnStr;
myWebConfig.Save();
if (user.ToLower().Equals("admin") && password.Equals("password"))
{
principal = new GenericPrincipal(new GenericIdentity(user), new string[] { "Users" });
return true;
}
else
{
principal = null;
return false;
}
}
In your DataService derived class override the CreateDataSource method and in it figure out the right connect string, create a new instance of the EF object context for the connection string and return it.
The WCF DS Service will not use the default constructor on the EF object context then, it's completely up to you construct the instance with the right connection string.
In your svc.cs file add following :
protected override NorthWindEntity CreateDataSource()
{
System.Data.EntityClient.EntityConnection connection = new System.Data.EntityClient.EntityConnection();
connection.ConnectionString = "";
NorthWindEntity ctx = new NorthWindEntity(connection);
return ctx;
}