I've hit a wall when it comes to how the Universal Windows Platform connects/manages/interacts with a local SQL Server database. My current project (WPF using .NET Framework 4.8) that I'm interested in porting over to UWP uses EntityFramework 6 with ADO.NET models and it works like a charm. No issues at all. UWP on the other hand, well I'll just say that I have absolutely no idea what's going on when it comes to connecting to a local instance of SQL Server. I've gone through about 3-4 different guides/templates and none have worked. I really want to use UWP and take advantage of all the new features coming for Windows 10 v2004, but it doesn't look like this will happen.
As I currently understand the process, I need to essentially create two separate projects within the same solution. One is the UWP main program and the other would be a .NET Core class library that targets the .NET Standard 2.0 platform. I also have read that EntityFramework 6 is not supported on .NET Core or UWP, so the only way is by using EntityFrameworkCore (more specifically NuGet package Microsoft.EntityFrameworkCore.SqlServer). So I installed it on the .NET Core class library and then set a reference from the UWP app to the class library. Because the local SQL Server is already up and running, I'm not doing what is called the 'code first' approach to the creation of all the models/DbContext.cs files. Based on what I've read, the ONLY way to import a currently existing SQL Server into the data model is by use of the Scaffold-DbContext command with a standard connection string through the package manager. Surprisingly, this worked on the first attempt and the models and DbContext were all created without any issues.
This is about as far as I seem to be able to get as everything after does nothing but throw exceptions. If I try to pass any C# code using the DbContext to retrieve any data from the database, I get about 10-15 exceptions that essentially say the program can't find or connect to the database. I have manually edited the connection string in every way imaginable, but nothing seems to work. I also tried to manually set up a new connection using Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient.SqlConnectionStringBuilder and System.Data.SqlClient.SqlConnection but they all fail with the same exceptions.
Sorry for the long post but at this point, I really don't know what's going on and would really appreciate any feedback you all could offer.
Update 1
So, I went back through my currently working app on .NET Framework and looked for the connection string in the App.config file to see what the regular EntityFramework is using and it's completely different than anything I've used before. My guess is that it's generating a completely custom connection string that includes references to all sorts of files and a property called 'ProviderName'. Will try cutting and pasting this string into UWP to see if it'll work.
Update 2
I think I'm missing something fundamental on this. I can generate the scaffold with a connection string without any issues, but if I attempt to open a connection at runtime using the same connection string, I'm getting errors.
Finally was able to get a connection at runtime after months of trial and error. Without getting into too much detail, here's what worked for me (assuming EFCore has already generated a DbContext file):
Enable Enterprise Authentication.
Enable TCP/IP connections to the SQL Server instance.
In Visual Studio's server explorer, click Add Connection. If you already have a connection saved for the database, right click the server and click Modify Connection
In the connection properties window, click the Advanced button. Make a note of all of the listed parameters and their values and save it.
Open the data context file that isn't able to connect and add a using statement for Microsoft.Data.SqlClient. Now locate the OnConfiguring method. Use a SqlConnectionStringBuilder and configure all of the parameters from the advanced connection properties that were saved earlier.
And that should work. If there are still errors, I would double check the parameters to make sure they were all entered correctly.
Hope this post will help out anyone else dealing with this issue.
Related
I can't seem to find anything related to this problem. So I have a web-app I'm building using AngularJS and the others (html,etc) for UI, which connects with an Entity Framework in Asp.net (Either API or MVC, I'm not sure) for rest calls. That then connects to a sql database for model retrieval.
I have a SQLCMD which executes a stored procedure and creates a new time-stamped file of records from the database. The idea is that users will be able to click a button in the interface and a file will be generated without anyone ever having to touch sqlserver that they cna then put into excel. This has lead me on a search of topics like "WebMethods to call sqlcmd", "Calling .net webmethods with Angularjs", and "executing stored procedures with ASP.net", but nothing seems to be similar to what I'm asking (which leads me to believe maybe I don't have the best idea and it can be done better).
Any ideas? Just some pointers on where I should start or how I can tackle the problem would be greatly appreciated. I don't even have to return anything, it just needs to execute so this file can be created.
Your problem has nothing to do with AngularJS.
AngularJS is just some client side code that will eventually call MVC or WebApi code (as you state).
Your problem is .. having server side dotnet code call an external .exe.
http://dotnetslackers.com/community/blogs/haissam/archive/2007/02/02/Run-Executable-file-in-ASP.NET.aspx
// Create An instance of the Process class responsible for starting the newly process.
System.Diagnostics.Process process1 = new System.Diagnostics.Process();
// Set the directory where the file resides
process1.StartInfo.WorkingDirectory = Request.MapPath("~/");
// Set the filename name of the file you want to open
process1.StartInfo.FileName = Request.MapPath("WindowsMediaPlayer.exe");
// Start the process
process1.Start();
You just need to get familiar with System.Diagnostics.Process.
One big gotcha will be permissions (that is running the IIS) being able to run sqlcmd.exe.
I ended up doing a completely different idea and exported directly from Angular, Export to xls using angularjs, and did'nt worry about .NET or SQL for it.
This was way simpler and is better for me since the user can actually select what they want to export rather than just a total database dump.
I'm trying to access the dataSet for a project that I just created and published through MS Project 2007 client, however, it turns out I need the project Guid to access it programmatically.
Here`s the code I want to run, from the msdn website:
public SaveProjectInfoToXml(Guid projectUid, string filePathName)
{
WebSvcProject.ProjectDataSet dsProject =
proj.ReadProject(projectUid, WebSvcProject.DataStoreEnum.PublishedStore);
dsProject.WriteXml(filePathName);
}
Question is, How do I get the projectUid for the project Id like to access!?
Why did microsoft decide to leave out such critical details?
Also, I cant run ReadProjectList() and loop through all the projects, because my permissions aren`t high enough.
Thanks
I solved my own problem
The method ReadProjectList() Requires elevated permissions to use. However, to simply get a list of all the projects available in the server, The method ReadProjectStatus() from the project web service should be used, as so:
ReadProjectStatus(Guid.Empty,WebSvcProject.DataStoreEnum.PublishedStore,String.Empty,0);
It will return a list of the datasets of all the projects available on server.
We are starting a new WinForms project and decided to use TeamCity to create builds and run unit and integration tests. The project deals with database. We have 3 databases (developDB (this is used by developers while developing =) ), testDB (this is used by teamcity to run tests) and productionDB(this is used by client)). TeamCity has 3 buildConfiguration. The first is triggered when commit happens. The second is triggered every night to run integration tests. And the third is triggered by developer when we what to make a release. So I want TeamCity to be able to change connectionString depending on what kind of build happens. Also I don't want to store connectionString in app.config (I don't want client to know the user and password). What options are available to perform the task?
Thanks in advance!
Updated
I use NHibernate and FluentNHibernate to connect to databases if it matters.
In this situation, I would use TeamCity to run a nant script to perform the build.
NAnt allows you to modify config file values (such as your connection string) at build time.
An example of using TeamCity/NAnt to deploy to different staging environments can be found at this blog post:
http://thecodedecanter.wordpress.com/2010/03/25/one-click-website-deployment-using-teamcity-nant-git-and-powershell/
As #surfen suggests, the connection string values for each environment should be encrypted to prevent credentials from being stored in plain text.
I have not used TeamCity, but I have written multiple applications with dynamically changing ConnectionStrings during logon process (ie. at runtime), and It's quite simple.
You didn't tell how do you connect to your Database. Since you mention app.config, I suppose it is ADO.NET DataSets or simmilar technology, which creates a read-only(getter) ConnectionString in your Settings.Designer.cs / app.config.
What I did, was to create a setter method in Settings.cs (not Settings.Designer.cs) for the ConnectionString property like this:
public void setNorthwindConnectionString(String value) {
this["NorthwindConnectionString"] = value;
}
My generated DataSet then uses this NorthwindConnectionString for accessing data.
You can use preprocessor directives for conditional setup of your ConnectionString:
#if DEBUG
Console.WriteLine("Mode=Debug");
Settings.Default.setNorthwindConnectionString("(DebugDBConnectionString)");
#else
Console.WriteLine("Mode=Release");
Settings.Default.setNorthwindConnectionString("(ReleaseDBConnectionString)");
#endif
You could also encrypt your connection strings, and copy the right app.config during post build event.
I am assuming you would be using msbuild to build your projects in Team city. If that is the case, then you can send the Conditional Compilation Symbol where in you can pass what ever symbols you need.
Once you have the symols, you can do things like:
#if DEVBUILD
//.... Your Connection String Code here
#endif
#if INTBUILD
.... Your Connection String Code here
#endif
That's the answer to your frst question.
Looking at the second part of your question, where in you do not want to store the user name & password in the app.config,
Options:
try intergrated security, it will use your domain account
if option cannot be used, try keeping your connection string as a Registry Key, so that its not obvious or an Environment variable.
When working in Ruby (specifically, in Rails), I can automatically run my tests using a testing database, and also choose easily between a development or production database. Still new to Entity Framework (WPF), but it seems less than simple.
My Entity assembly has an App.Config file that holds a reference to the database, and I need to copy this App.Config file to all runnable projects (e.g. questions 1113361 and 2233897).
If I use Test->Database Test Configuration without explicitly copying App.Config from my EF project, I get
System.ArgumentException: The
specified named connection is either
not found in the configuration, not
intended to be used with the
EntityClient provider, or not valid.
which is the same as if I have a missing or different App.Config file.
Strangely even if I do change all the connection stings in my Entity project and testing project to the same database, I still get that error.
Is there a step I'm missing when telling Visual Studio (2010 Ultimate) that I want my tests to run using a different testing database, or is this just not supported with EF 4?
Also, Is there some way to change database context other than copying App.Config files back and forth? Seems like a serious way to ignore separation of concerns if not, so I think I'm missing something.
Strangely, as I was playing around after doing this, it started working. Somebody might comment on this, but it looks like I was using Test->Database Test Configuration at the wrong time.
To wit:
Clean project, no App.Config, use Test->Database Test Configuration to set the test database. It generates an app.config (lowercase, notably). You get an error. Even if you check all the connection strings (weird)
Clean project, first copy the App.Config from from you Entity project. Now when you use Test->Database Test Configuration, it will populate the App.Config that you copied, and it works.
I imagine it was some issue I was creating when copying the connection strings.
I've also confirmed that this works with my Entity project using a "Main" database while my testing project uses a "Test" database.
Wonder if someone can confirm/clarify this?
I have been tasked with writing an installer with a silverlight out of browser application. I need to.
get the version off a local EXE
check a web service to see that it is the most recent version
download a zip if not
unpack the zip
overwrite the old EXE
start the EXE
This installer app is written in .NET WinForms now but the .NET framework is an obstacle for people to download.
The recommended solution is to use a SLOOB however i am not sure how to assign full trust. If i assign full trust can I start a process.
Thanks
Looking into this, I suspect you're going to have to create the process using WMI through the COM interface. At the end of the day, that makes this a very difficult option and very subject to failure due to a host of reasons (WMI being disabled or secured, user won't give full trust, etc.) I suspect you would be much better off creating a .msi deployment package or something similar that was able to go out and download the framework, if necessary. There are a lot of deployment models available, almost all of which feel superior to this one.
That said, if you're going to do this:
To get the COM object, you're going to want to use the AutomationFactory.CreateObject(...) API. Tim Heuer provides a sample here.
To actually do the WMI scripting, you're going to want to create the WbemScripting.SWbemLocator object as the root. From there, use the ConnectServer method to get a wmi service on the named machine. You can then interrogate the Win32_Process module to create new processes.
Edit: I spent a little time working on this and, even on my local machine as Admin I'm running into security problems. The correct code would be something similar to:
dynamic locatorService = AutomationFactory.CreateObject("WbemScripting.SWbemLocator");
dynamic wmiService = locatorService.ConnectServer("winmgmts:{impersonationLevel=impersonate,authentationLevel=Pkt}//./root/cimv2");
dynamic process = wmiService.Get("Win32_Process");
dynamic createParameters = process.Methods_["Create"].InParameters.SpawnInstance_;
createParameters.CommandLine = "cmd.exe";
wmiService.ExecMethod("Win32_Process", "Create", createParameters);
Silverlight 4 will have support for something like this: http://timheuer.com/blog/archive/2010/03/15/whats-new-in-silverlight-4-rc-mix10.aspx#sllauncher