0

Wanted to use SQL with EF6 in my Prism MVVM WPF App. Since I am new to EF6 I first made a simple sample that works just fine. In this sample I use one module and have 3 folders for Views, ViewModels and Models, the latter holding the SQL stuff.

So I translated the concept to my Prism App. Here I have a different structure. A 'Root' Module with the bootstrapper in the root and the MainShell and its Viewmodel in Views and ViewModels folders Respectively. I than have a folder Modules which holds 2 projects. in project 'Data' I have my EF logic in the 'SQL' folder. And in the project 'MainView' I have the MainView and the MainViewModel in the Folders 'Views' and 'ViewModels' respectively. Now when I compile I get the following message: 'No connection string named 'Entities01' could be found in the application config file'.

I then added the configuration string to the configuration file (App.config) in both the 'Root' Module and the 'MainView' Module. I also updated the paths to reflect the new location. But I now get a different error message.

System.Data.Entity.Core.MetadataException: 'The specified metadata path is not valid. A valid path must be either an existing directory, an existing file with extension '.csdl', '.ssdl', or '.msl', or a URI that identifies an embedded resource.'

To me this indicates that I did not change the path correctly.

Original (as created by EF6) connection string as follows:

  <connectionStrings>
    <add name="Entities01" connectionString="metadata=res://*/SQL.DB01.csdl|res://*/SQL.DB01.ssdl|res://*/SQL.DB01.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=DESKTOP-14K5J6E\DB01;initial catalog=NLTrader01;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

I than modified the above code to the following to reflect the new location:

  <connectionStrings>
    <add name="Entities01" connectionString="metadata=res://*/Data/SQL.DB01.csdl|res://*/Data/SQL.DB01.ssdl|res://*/Data/SQL.DB01.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=DESKTOP-14K5J6E\DB01;initial catalog=NLTrader01;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

I am at a loss as how to fix this. Is my approach just wrong or did I just make a typo in the new path?

I did add the using directives. I have also added EF6 to all projects. And I also added a reference to the 'Data' Project.

Joey Joystick
  • 145
  • 1
  • 11
  • If your EDMX file is in folder `Models/Data/SQL` (as I understood from your description) - use `metadata=res://*/Models.Data.SQL.DB01.csdl...` (and the same for ssdl and msl). So basically all subfolders in which your edmx file resides separated by dot. – Evk Mar 03 '18 at 16:24
  • I tried this and the previous error message is gone and replace by a different message. Seems the issue described above is solved though. The message I am getting is the following. System.Data.Entity.Core.MetadataException: 'Unable to load the specified metadata resource.' Thanks for the tip though. I would never have thought of it myself and it seems to be able to locate the database this time, so that is an improvement I guess. To bad a failed elsewhere... – Joey Joystick Mar 03 '18 at 16:41
  • Well that most likely means connection string is still wrong. Try to read this article for troubleshooting this problem: http://www.craigstuntz.com/posts/2010-08-13-troubleshooting-entity-framework-connection-strings.html. But first ensure that your model is named "DB01" and is locatedin folder "SQL", which is in folder "Data", which is in folder "Models", which is in the root of the project. If not - fix that up. – Evk Mar 03 '18 at 16:47
  • Had a PowerCut here. Anyway, back now. I got it working by using the general notation. res://*/; Good enough for now, but as described in the article it really slows things down. Not quite sure yet what was wrong with the proper notation though. I will get back to this at a later stage. I really appreciate your help and guidance on this. – Joey Joystick Mar 04 '18 at 19:40
  • Ok it is solved now. The first answer that Evk gave before is correct and this basically solved the issue at hand. There was an additional unrelated issue which I had not paid attention to. The namespace in the viewmodel was incorrect. I have indeed placed 2 modules inside a folder, but this folder is not included in the namespace. That is ok. However, if you do this in the view you also need to do this in the viewmodel. Avoid using the earlier mentioned short notation; res://*/; This slows things down significantly. How do I mark your answer as the correct answer in these comments? – Joey Joystick Mar 05 '18 at 18:53
  • Well you can't but don't bother :) If you want, you can post answer to your own question, for the benefit of future visitors. – Evk Mar 06 '18 at 07:25

1 Answers1

0

There are at least 2 answers to the above. Thanks to Evk for the first answer and guiding me in the direction for additional information.

My personal preference goes to the following answer.

<connectionStrings>
    <add name="Entities01" connectionString="metadata=res://*/Data.SQL.DB01.csdl|res://*/Data.SQL.DB01.ssdl|res://*/Data.SQL.DB01.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=DESKTOP-14K5J6E\DB01;initial catalog=NLTrader01;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

It is however also possible to use the following notation.

<connectionStrings>
    <add name="Entities01" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string=&quot;data source=DESKTOP-14K5J6E\DB01;initial catalog=NLTrader01;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

I noticed that this solution is significantly slower than the first solution.

From the MS Documentation it is my understanding that there is yet another solution that should be slightly quicker again, but I have not figured that out yet, once I have I will add that to the solution.

There was an other issue that I had overlooked though.

When using Prism with the Prism ViewModelLocator you have to keep in mind that it is looking for the ViewModel in the folder 'ViewModels'. The workings of the ViewModelLocator are based on the assumption that the View is always located in the 'Views' Folder and the ViewModel is always located in the 'ViewModels' folder. And these 2 folders are again in the same root. So if you are using additional folders in order to organise your project, keep in mind that the NameSpace should not reflect the actual folder structure, but the structure as described above in order to make the ViewModelLocator work.

Joey Joystick
  • 145
  • 1
  • 11