0

I have a VS11 beta WPF application with a Microsoft Datagrid based on a table from an Entity Framework 5.0b2 model (from an sql server database). (The grid uses whatever code was autogenerated by adding a data source from an entity framework model and dragging and dropping a table from that model to the design surface.). I then used the EF5.0 DBContext code generator add-in to generate DbContext types that I could use in the app.

The result was not good. I got a compile error that seems unfixable; at least my attempts made things worse. The datagrid does not like DbContext and doesn't co-exist with it (when both the datagrid and DbContext are based on the same database and tables). Is there a workaround, maybe by changing the code generator template?

The error message is pasted at the end. Thanks for any help or insight on this.

(note the following closely related post isn't an answer because though I can convert dbcontext to objectcontext, I can't get datagrid to work properly with it when I do; and if I convert objectcontext to dbcontext, I don't have the autogenerated dbcontext types: Convert DBContext to ObjectContext for use with GridView). I'm looking for a fairly simple workaround--I'm sure there's a workaround if I start hand coding all types and conversions, but I want to keep the ease of using the autogenerated code--I don't want to be occupied with work the code generator can, and so should, do. If there isn't a solution, I suppose I'll base the controls on ado.net and leave entity framework for non-ui code.

Error
Cannot implicitly convert type 'System.Data.Entity.DbSet' to 'System.Data.Objects.ObjectQuery'

Documents\Visual Studio 11\Projects\WpfApplication3\WpfApplication3\MainWindow.xaml.cs

The line that caused the error (created by Microsoft drag and drop of the datagrid with an EF table as the source): System.Data.Objects.ObjectQuery myTblsQuery = myDbsEntities.MyTbls;

Community
  • 1
  • 1
techvslife
  • 2,273
  • 2
  • 20
  • 26
  • I think this may be to do with EF not supporting manual compiled queries. but thats just a guess – undefined Mar 25 '12 at 04:44
  • There's entity framework on both sides (it has two different apis), the datagrid control is using the object context api, and that doesn't work with the dbcontext api. There's a conflict because the whole convention in these orm frameworks is to use the actual object names for types; which is reasonable enough if it wasn't for this odd case of the same orm (EF) having two apis. There should be a simple solution... – techvslife Mar 25 '12 at 05:56

1 Answers1

0

The code gnerated by drag and drop in the WPF designer was never very good and the WPF team haven't updated it to work with DbContext. Your best bet is either to drop down to ObjectContext like the other answers suggest or to use the much better WPF data binding supported by DbContext but do so without using drag-and-drop.

WPF data binding with DbContext is pretty easy because the Local property of each DbSet is actually an ObservableCollection which WPF naturally binds to very well. So for example you end up binding your view sources something like this:

categoryViewSource.Source = _context.Categories.Local;

This blog post contains more details: http://blogs.msdn.com/b/adonet/archive/2011/03/14/10138486.aspx

Arthur Vickers
  • 7,503
  • 32
  • 26
  • I saw that blogpost, as well as the directions here: – techvslife Mar 25 '12 at 19:38
  • thanks, I saw that, as well as the directions here: http://msdn.microsoft.com/en-us/library/gg197522(v=vs.103).aspx But it didn't work--I wasn't able to get any data to load. I did have to make one change: the database comes first and I need to autogenerate the dbcontext code, so I relied on the autogenerated dbcontext code (the ef5.0 dbcontext code generator add-in for vs11) and made additions to make it consistent with the directions, but the datagrid failed. I'll look it over again,but: 1) I have to rely on the autogenerator for the dbcontext code--the dbs is huge; 2)keep things simple. – techvslife Mar 25 '12 at 19:46
  • The problem may be that those directions microsoft provided are code first. I doubt this in the dbcontext code (in the directions) is enough to load data into the grid from sql server: _context.Departments.Load(); departmentViewSource.Source = _context.Departments.Local; The autogenerated code for a working wpf datagrid (using legacy ObjectContext) is like this: System.Data.Objects.ObjectQuery departmentsQuery=this.GetDepartmentsQuery(SchoolEntities); departmentsViewSource.Source=departmentsQuery.Execute(System.Data.Objects.MergeOption.AppendOnly); – techvslife Mar 25 '12 at 20:56
  • Once DbContext has found a model it behaves exactly the same for Code First and Database First. For example, the data binding to Local works the same. The ObjectContext/ObjectQuery code in your comment is essentially doing the same thing as the DbContext/DbQuery code. Both get you a collection of entities in memory that is then bound to the data source. The main difference is that the DbContext version will work better because DbContext is providing an ObservableCollection, while the ObjectContext code is not. – Arthur Vickers Mar 25 '12 at 21:44
  • Thanks, then I don't know why the code doesn't work. I just started using EF, so I must be overlooking some obvious needful line. The sample code in the msdn article and post does not retrieve anything from the backend database (unlike the code generated by the grid using ObjectContext, which works fine). Or it could be something is off in dbcontext code generator, though its code looked the same as the msdn sample code. Actually, there are no calls to dbquery in in the project code (after doing a quick search), but none in the sample code either. – techvslife Mar 26 '12 at 01:51
  • If I saw a wpf datagrid sample that used dbcontext code generated by the dbcontext add-in (i.e. database first) to hookup a database table and load values from it, I'd figure out quickly what lines were missing. But I've been faithful to the sample code and it's not working so far. – techvslife Mar 26 '12 at 02:07
  • It's possible that you are using Code First by mistake. Check out this limk to troubleshoot this. http://blog.oneunicorn.com/2012/02/26/dont-use-code-first-by-mistake/ – Arthur Vickers Mar 26 '12 at 20:12
  • Thanks for the link. I do already have all the "database first" lines the piece mentions in my project; they were created by the dbcontext code generator from the edmx model of my sql server database. The problem is that there are no msdn code samples on how to link that (database first dbcontext) code to a wpf datagrid. None of the code examples I've seen work, not with database first code that was generated by the dbcontext code generator. (If someone at Microsoft had a sample of database first code using dbcontext wired to a simple, functional wpf datagrid, that would be a big help...) – techvslife Mar 26 '12 at 20:30
  • I went through the MSDN "Walkthrough: Data Binding with WPF" that you linked but replaced the "Defining the Model and the DbContext Derived Classes" section with a Database First flow by choosing to Add New ADO.NET Entity Data Model and then choosing the DbContext code generation. I had to copy the connection string from the class library app.config to the WPF application app.config (since the walkthrough uses two projects) but then it worked just like the Code First version. – Arthur Vickers Mar 26 '12 at 22:34
  • BINGO. That was it. Thank you for your patience with me on this. The app.config in the WPF project was missing the connection string that was in the class library app.config--I suspect it wld have taken me a pretty long time to see that was the cause on my own (no error was being thrown). (btw I noticed ef 5.0b2 will install only to the first project in a multi project solution; package console manager gives an error on trying to install it to the other projects. I manually added ef5.0 file references on the other projects in the solution using ef (perhaps that was unnecessary).) Thanks! – techvslife Mar 26 '12 at 23:28
  • You should have seen an exception. The generated DbContext code calls the base constructor with : base("name=SomeConnectionStringName"). If DbContext doesn't find a connection string with this name in the app.config when it should throw. I'm curious as to why you weren't seeing this. Did you change that line? Did you have another connection string with the same name in the WPF app.config? – Arthur Vickers Mar 26 '12 at 23:54
  • I do see that base constructor call. The only connection string I had was in the class project. There were no connection strings in the wpf app project, but no exception was thrown. Just to confirm, I deleted the connection string again now (from the wpfapp project) and ran it (f5); no exception but I got an empty datagrid. I put back the connection string, and the data appeared in the datagrid. Here is the entire original app.config: – techvslife Mar 27 '12 at 00:01
  • ok, now I see that call you mention was only in the class library (.context.cs) file: it had: public partial class MydbsEntities : DbContext { public MydbsEntities() : base("name=MydbsEntities") { } In the wpf app main window cs I have this: public partial class MainWindow : Window { private MydbsEntities _dbc = new MydbsEntities(); public MainWindow() { InitializeComponent(); } //(but this is as it is in the sample code) – techvslife Mar 27 '12 at 00:13