Print Page | Close Window

Database First

Printed From: IdeaBlade
Category: Breeze
Forum Name: Community Forum
Forum Discription: Build rich JavaScript apps using techniques you already know
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3804
Printed Date: 16-Apr-2024 at 5:15am


Topic: Database First
Posted By: mike963
Subject: Database First
Date Posted: 16-Nov-2012 at 7:58am
Hi

I have tried Breeze with an existing EF implementation that was developed DB first.

I get an error _contextProvider.Metadata();

Creating a DbModelBuilder or writing the EDMX from a DbContext created using Database First or Model First is not supported. EDMX can only be obtained from a Code First DbContext created without using an existing DbCompiledModel.

Originally I had the EDMX file in a separate Data Access Layer but have also tried it locally but still get same error

Any advice ?

Stack Trace

   at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
   at Breeze.WebApi.EFContextProvider`1.GetCsdlFromDbContext(DbContext dbContext)
   at Breeze.WebApi.EFContextProvider`1.GetJsonMetadataFromDbContext(DbContext dbContext)
   at Breeze.WebApi.EFContextProvider`1.Metadata()
   at UsingBreeze.Controllers.BreezeSampleController.Metadata() in d:\ModuleChooser\UsingBreeze\Controllers\BreezeSampleController.cs:line 19
   at lambda_method(Closure , Object , Object[] )
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
   at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)



Replies:
Posted By: brian.shirley
Date Posted: 16-Nov-2012 at 8:42am
I am also encountering this exact same problem.  

I created an EDMX file with one table from an existing database.  I then used the http://visualstudiogallery.msdn.microsoft.com/da740968-02f9-42a9-9ee4-1a9a06d896a2 - DbContext generator template so that the model used DbContext rather than ObjectContext and generated a POCO.

When calling directly via a WebApi method such as below, I receive JSON data as expected.

BrokerCommContext DbContext = new BrokerCommContext();
return DbContext.CommissionDesignations.AsEnumerable();

However, when invoking the method from the EFContextProvider I receive the same error as identified by Mike in the original post.

readonly EFContextProvider<BrokerCommContext> _contextProvider =
            new EFContextProvider<BrokerCommContext>();
[HttpGet]
        public string Metadata()
        {
            return _contextProvider.Metadata();
        }

I am really looking forward to getting Breeze out there with this project.  Any help is greatly appreciated!

Code Generated from EDMX
 public partial class BrokerCommContext : DbContext
    {
        public BrokerCommContext()
            : base("name=BrokerCommContext")
        {
            this.Configuration.LazyLoadingEnabled = false;
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public DbSet<CommissionDesignation> CommissionDesignations { get; set; }

Originally posted by mike963

Hi
I have tried Breeze with an existing EF implementation that was developed DB first.
I get an error _contextProvider.Metadata();
Creating a DbModelBuilder or writing the EDMX from a DbContext created using Database First or Model First is not supported. EDMX can only be obtained from a Code First DbContext created without using an existing DbCompiledModel.
Originally I had the EDMX file in a separate Data Access Layer but have also tried it locally but still get same error
Any advice ?
Stack Trace
   at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
   at Breeze.WebApi.EFContextProvider`1.GetCsdlFromDbContext(DbContext dbContext)
   at Breeze.WebApi.EFContextProvider`1.GetJsonMetadataFromDbContext(DbContext dbContext)
   at Breeze.WebApi.EFContextProvider`1.Metadata()
   at UsingBreeze.Controllers.BreezeSampleController.Metadata() in d:\ModuleChooser\UsingBreeze\Controllers\BreezeSampleController.cs:line 19
   at lambda_method(Closure , Object , Object[] )
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
   at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)


Posted By: jtraband
Date Posted: 16-Nov-2012 at 10:49am
Hm,  we have several test cases that use Database first models.

The EFContextProvider<T> generic argument "T" can be either a DbContext or an ObjectContext. 

So with EF "Database first",  you should have an EFContext class that looks something like.

    public partial class NorthwindIBContext : ObjectContext {
    ...

    }

The Breeze EFContextProvider can then be used like this


    public class NorthwindIBContextProvider: EFContextProvider<NorthwindIBContext>  {
        public NorthwindContextProvider() : base() { }
   
        // any public override here like BeforeSaveEntity or BeforeSaveEntities...
     
    }

And then your api controller might look something like this

    public class NorthwindIBModelController : ApiController {

        private  NorthwindContextProvider _contextProvider = new NorthwindContextProvider();

        [AcceptVerbs("GET")]
        public String Metadata() {
          return _contextProvider.Metadata();
        }
        ...
    }

Also, note that the example above uses an [AcceptVerbs("Get")] attribute instead of an [HttpGet] attribute.  I'm not really clear on the distinction between these two, but just to be safe ...

If this doesn't work, let me know and I'll try to post an entire working example with an DataBase first model.


Posted By: brian.shirley
Date Posted: 16-Nov-2012 at 11:11am
I switched to the [AcceptVerbs("GET")] annotation for good measure and still no luck.

I'm wondering if the conflict is due to the fact that my Database First  EDMX model is generating a class derived from DbContext rather than ObjectContext due to the DbContext generator template I linked to above.  I went this route in order to get true POCOs and DbSet<T> with DbContext API.  

I will try to do a traditional database first example that derives from ObjectContext to see if I still get issues.

Have you tried any examples this way?

For reference, Error:
Creating a DbModelBuilder or writing the EDMX from a DbContext created using Database First or Model First is not supported. EDMX can only be obtained from a Code First DbContext created without using an existing DbCompiledModel.


Posted By: jtraband
Date Posted: 16-Nov-2012 at 11:22am
Ok, I think I understand what is happening. 

Our internal tests are all built against "Database first" models built several years ago with an "ObjectContext".  With the advent of EF 4.1, EF "Database first" now defaults to creating a context that derives from DbContext and uses POCO entity classes.  We need to add tests for this, because evidently the DbContext that EF4.1 creates for "Database first" models is subtly different from that created for CodeFirst models, where we have a number of tests.

We will try to have this cleared up and a patch put together by this evening.  But until then, you can still use an "old" ObjectContext by following the instructions in this link.

http://msdn.microsoft.com/en-us/data/jj556581.aspx - msdn.microsoft.com/en-us/data/jj556581.aspx


Posted By: brian.shirley
Date Posted: 16-Nov-2012 at 11:30am
I created a simple database first model that uses ObjectContext as a test and it worked as stated, so progress!!

Thank you very much for the quick responses on this and all of the hard work on Breeze.


Originally posted by jtraband

Ok, I think I understand what is happening. 

Our internal tests are all built against "Database first" models built several years ago with an "ObjectContext".  With the advent of EF 4.1, EF "Database first" now defaults to creating a context that derives from DbContext and uses POCO entity classes.  We need to add tests for this, because evidently the DbContext that EF4.1 creates for "Database first" models is subtly different from that created for CodeFirst models, where we have a number of tests.

We will try to have this cleared up and a patch put together by this evening.  But until then, you can still use an "old" ObjectContext by following the instructions in this link.

http://msdn.microsoft.com/en-us/data/jj556581.aspx - msdn.microsoft.com/en-us/data/jj556581.aspx


Posted By: jtraband
Date Posted: 17-Nov-2012 at 3:09am
There is a new Breeze version 0.71.3 available now that should fix this issue.

With this version, you should be able to create an EFContextProvider with a "Database First" DbContext .




Posted By: brian.shirley
Date Posted: 17-Nov-2012 at 8:03am
I just pulled down the latest from NuGet and it is working perfectly.  Thanks again for the quick turnaround.  Stellar.



Print Page | Close Window