This project is read-only.

Doesn't seem to work with Entity Framework Code First?

Oct 26, 2011 at 4:47 PM
Edited Oct 26, 2011 at 4:49 PM

Hi, I stumbled across this project on CodeProject, so thought I'd give it a try. However, it doesn't seem to work with EF Code First? I've tried doing the following to get the ObjectContext:

            var shape = new EntityGraphShape4SQL(((IObjectContextAdapter)context).ObjectContext)
                .Edge<Customer, Order>(x => x.Orders);

 

But when I call the load, I get a SqlException: "Login failed for user 'XYZ_User'."

This is wrong though, because if I just do context.Customers.ToList(), there's no problems whatsoever in getting the data. It seems that when I pass the Context into EntityGraphShape4SQL, it loses the password for the connectionString. The string that I see is:

metadata=reader://b66c5cf3-e153-44d7-8b41-9902823a5580;provider=System.Data.SqlClient;provider connection string="Data Source=.\SQLEXPRESS;Initial Catalog=MyDatabase;User ID=XYZ_User;MultipleActiveResultSets=True;Connect Timeout=30;Application Name=EntityFrameworkMUE";


So, for some reason the password is missing from the connectionString? Any ideas why this works fine if I use the DbContext directly, but fails if I call shape.Load(entity)?

Oct 26, 2011 at 5:11 PM
Edited Oct 26, 2011 at 5:13 PM

It appears that the reason is because the DbContext does not expose the password in the connectionString property. I modified your code to accept a connectionString to test this. However, now it's literally mapping the entity names to the table names. I.e. my Entity is called Order, but the table is called ABC_Order. This will give the exception Invalid object name 'Orders', which is obviously wrong as it should get the table by the name ABC_Order. Again, this works fine if called directly through EntityFramework.

Oct 26, 2011 at 5:23 PM
Edited Oct 26, 2011 at 5:23 PM

A simple Load<Customer>() fails as well: Invalid object name 'Customers'. EntityFramework is setup explicitly to use ABC_Customer:


            builder.Entity<Customer>().HasKey(x => x.CustomerId);
            builder.Entity<Customer>().ToTable("ABC_Customer");


It only fails when used through shape.Load(), it works fine when executed via the context.

Oct 26, 2011 at 7:08 PM

Hi,

Thanks for trying out this stuff and I'm sorry that it doesn't work out-of-the-box.

The password thing might be a security issue (or maybe a dbcontext bug?).

Please note that I haven't tested my stuff with code-first/dbcontext so it might or might not work.

Then w.r.t. to your second issue. I simply haven't implemented mappings. That is, I'm assuming that there is a direct correspondence between entity types and table names and between property and column names.

My primary goal with the project was to get a very fast and declarative method for doing very complex queries. The project for which I implemented this stuff didn't require such mappings, so I didn't invest in supporting it.

In case you want to add such mappings yourself, I might be able to support you.

Kind regards,

Merijn

Oct 27, 2011 at 10:18 AM

Thanks Merijn. I'll have a look at what's involved. To be honest I may just make my own, specific to Code First.