Y
Y
Yurii Medvedev2014-05-13 14:59:23
Microsoft
Yurii Medvedev, 2014-05-13 14:59:23

How to deploy an application via ClickOnce using Entity Framework?

Decided to take a closer look at the world of EF. Since I use MySql for work, I conducted all the experiments on it. For consistency, here is a basic list of required steps that I follow to create a test case:
1. Machine stuffing: Windows 8.1 Pro, VS2013, MySQL Connector 6.8.3, MySQL for VS 1.2 2. Create a C# 3
console application in VS I
add a new element to the project:
0a6949552c5d49a39ded878eaa42854b.png
4. Select the desired model:
c09d029e943e4c3391a5e3383d2c1c05.png
5. Select (or create a new one, if it does not exist) connection:
25456e3ab5bd40bd8efb33a63fdcdaa7.png
6. Select the EF 5.0 version (although there are no special options):
bb1d7dcb051a4b808ac318d2f3f6f026.png
7. For simplicity of the experiment, we will select one table:
bceba6d8b31f4d22a7877721b1bacc2e.png
8. In the appeared App.config file, we will correct the database address (127.0.0.1 -> 192.168.0.37) so that in the end the resulting application can be run on different machines:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="DbEntities"
         connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=192.168.0.37;user id=root;password=blablabla;persistsecurityinfo=True;database=testbase&quot;"
         providerName="System.Data.EntityClient" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  </entityFramework>
</configuration>

9. We write a simple code that displays the number of records in the table:
using System;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                DbEntities context = new DbEntities();
                int count = (from a in context.t_abook
                             select a).Count();

                Console.WriteLine("Count records = {0}", count);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception:\n{0}\n", ex.Message);

                if (ex.InnerException != null)
                    Console.WriteLine("InnerException:\n{0}\n", ex.InnerException.Message);

                Console.WriteLine("Stacktrace:\n{0}", ex.StackTrace);
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }
}

10. We start. Everything works great.
3029dec779de4d7f8214cda2d1de4d42.png
11. Now open the project properties, on the Signing tab create a test certificate, sign the manifest.
12. On the Publish tab, let's take a look at the files that go into the final project:
abc69a64cfaa4f73ac9b779d921c73c0.png
13. Publish the whole thing somewhere
14. Just in case, check again if everything works? Let's run ConsoleApplication1.application, the deployment is successful. The application showed the number of records in our table without any problems, as in the previous example.
Everything seems to be fine, but if we now run ConsoleApplication1.application on another machine, not a development one, we will get an error message - the specified storage provider was not found in the configuration or is invalid.
e21c9986e19445b588ab278587e4ce8a.png
Empirically, it was found that the application cannot load MySql.Data.MySqlClient from the GAC. If you install MySQL Connector 6.8.3 on the client machine, the problem disappears. This solution could be used if it had to be done a couple of times, but in reality the application will have to work on about 70-80 computers, you don’t run into (Besides, running the installer requires admin rights.
I also tried to create an application using EF6 from NuGet (like choosing
MySQL.ConnectNET.Enity ) - the same effect.
I apologize for the abundance of text, I'm just new to EF, maybe I made a mistake at some step, so I wanted to explain in detail the sequence of my actions.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vasily Samoilov, 2014-05-13
@kin9pin

In my project, I did this:

<system.data>
    <DbProviderFactories>
      <remove invariant="MySql.Data.MySqlClient" />
      <add
          name="MySQL Data Provider"
          invariant="MySql.Data.MySqlClient"
          description=".Net Framework Data Provider for MySQL"
          type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, 
                  Version=6.8.3.0, Culture=neutral, 
                  PublicKeyToken=c5687fc88969c44d"
      />
    </DbProviderFactories>
  </system.data>

Well, MySql.Data.dll + MySql.Data.Entity.dll is copied to the output directory during assembly.

O
Oleg, 2014-05-13
@chaek

In the project settings Publish -> Prerequisites, checkboxes set the packages that must be installed if they are not available before starting the application. If there is no package you need, then you can create it yourself and add it to the listed list ( msdn.microsoft.com/en-us/library/ms165429.aspx , archive.msdn.microsoft.com/bmg ). This is how I solved the problem with EF Firebird.

D
Dmitry Guketlev, 2014-05-13
@Yavanosta

And putting a lib in the folder with the program will not work? I think for this it will be enough to set the Copy Local property of the reference to Copy Always.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question