I am pretty new to entity framework, but given a simple object like this:
public class Country
{
public string Name { get; set; }
[Key]
public string Code { get; set; }
public bool IsPostalCodeRequired { get; set; }
public ICollection<Province> Provinces { get; set; }
}
returned by a DbContext, the Provinces property is null. If I use the Include method on my linq statement to include provinces, then it works. But I was wondering if there's a way to load them when I actually access the property? I know there's performance concerns to think about here, but I just want to know how to do it.
Thanks,
Make sure ObjectContext.ContextOptions.LazyLoadingEnabled is true. This is the default for a new project.
If using pure POCO entities, lazy loading can't work (think about it). So you can use POCO proxies. Again, this is the default, but making lazy loading work with POCO proxies requires that all the relationship properties are declared virtual, and yours aren't.
Craig said it all. Just wanted to say by default ObjectContext has LazyLoading turned off . Although when you create new .net 4.0 project, the model designer explicitly turns it on for u for .net 4.0 projects. Its turned off because EF needs to preserver legacy behavior of .net 3.5 when lazy loading was not available. However as you may notice that you are using Dbcontext which is new and has no dependency to .net 3.5. Hence LazyLoading would be enabled by default to give you seamless experience.
Related
Is there any way to only allow Entity Framework classes to write/read the EmailJson property ? The code works without this but it would be much cleaner if this property could not be altered by any code since having invalid json in it would throw an exception.
I cannot use a backing property because of the generic requirement.
public class EmailEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string EmailJson { get; set; }
public T GetEmail<T>() where T : BaseEmailModel
{
return JsonConvert.DeserializeObject<T>(EmailJson);
}
public void GetEmail<T>(T emailModel) where T : BaseEmailModel
{
EmailJson = JsonConvert.SerializeObject(emailModel);
}
}
I suggest using a seperate data access tier (for example a class 'EmailEntityService') that is responsible for all access to EmailEntity. All code throughout your solution should only use this service then. If you move EmailEntity to a seperate project you can ensure that access to it is only possible via EmailEntityService (if you keep that service in a project holding a reference to the 'entity project').
So at the end you have (at least) three projects:
1: Entity project
2: Entity services project (with a reference to 1, this project ensures entities cannot be altered directly)
3: Business logic project (with a reference to 2 but not to 1 to prevent direct access to entities)
Since entity classes are just POCOs I don't see any other possibilities to do this on a more technical/basic way.
I am EF new learner, i have some questions to ask:
1.
I don't understand what does virtual mean in for example one to many, i give an example:
one question can have many options for e.g.
public class Question
{
public int QuestionId { get; set; }
public string Title { get; set; }
public virtual List<Option> Options { get; set; }
}
public class Option
{
public int OptionId { get; set; }
public string OptionText { get; set; }
public virtual Question Question { get; set; }
}
but what does the "2" virtual mean, because if i delete the virtual in this line:
public virtual List<Option> Options { get; set; }, i didn't find any differences, it works well as one to many, so can you explain me very clearly and easily what the 2 virtual mean, if it's override, override what?
2.
I don't know when we should use API fluent, for e.g. the previous one to many ex. without api fluent, it's still a one to many Relationship, so please just tell me when we should use it ? in which occasions for example.
3.
in the API fluent, i know "withmany" and "hasmany" together, they mean "many to many", and what's "withrequired? isoptional? "
I think I can answer following points:
EF define all navigation property virtual, so that EF will at runtime create a new class (dynamic proxy) derived from your Brand class and use it instead. This new dynamically created class contains logic to load navigation property when accessed for the first time. This feature is called lazy loading (or better transparent lazy loading).
See the following link for more detail
Entity Framework 4.1 Virtual Properties
2.When to use fluent API
When working with Code First, you define your model by defining your domain CLR classes. By default, the Entity Framework uses the Code First conventions to map your classes to the database schema. If you use the Code First naming conventions, in most cases you can rely on Code First to set up relationships between your tables based on the foreign keys and navigation properties that you define on the classes. If you do not follow the conventions when defining your classes, or if you want to change the way the conventions work, you can use the fluent API or data annotations to configure your classes so Code First can map the relationships between your tables.
http://msdn.microsoft.com/en-us/data/jj591620.aspx
3.See the following link to know What is .WithRequired and .WithOptional options
What part does the .WithRequired play in an EF Fluent API?
Is it possible to have Code First data classes declared with internal access as shown:
internal class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
I have a requirement that classes and its properties should not be visible outside of the assembly.
As long as your DbContext derived class that exposes your class to EF is in the same assembly, you should be able to. I don't happen to design my apps that way as I prefer more separation. But the context should be able to build the model and it should be able to interact with the classes (e.g. execute queries, save changes etc) if they are in the same assembly since it will have access to the internal class. Even with the various odd things we tried and wrote about in the Code First book, I never happened to try this particular scenario.
While working with EF code first I get error given below at different times:
The entity type SomeType is not part of the model for the current context.
What are the possible causes of this error?
It may occur because:
DbContext configured with an incorrect connection string
The entity specified is actually not mapped in configuration
I got this when my class that inherited from DbContext did not declare the model as a property. For example, I neglected to add a property for FooModel in the code below:
public class MyDBContext : DbContext
{
public DbSet<FooModel> FooModels{ get; set; }
// etc. ...
}
This message also appears if you try to do somthing such a set an EntityState on a child collection in a one-to-many association.
For example; if a one-to-many association exists between ParentEnt and ChildEnt in the code snippet below, the error message:
The entity type Hash1Type is not part of the model for the current context.
MyDbContext.Entry(ParentEnt.ChildEnt).State = EntityState.Unchanged;
The following change does not produce an error:
MyDbContext.Entry(ParentEnd.ChildEnt.First).State = EntityState.Unchanged;
Note that the use of First() in this case may indicate t
This can also be caused by properties on your POCO not named EXACTLY as they are in the EDMX/modelbuilder. Please see my post here for details on how I trouble shot the issue.
The entity type <class> is not part of the model for the current context
I had this error.
It turned out I had added a new field to a db View a few hours before. I updated the context (as part of something else I was doing) and got this error.
When I updated the POCO's all was well: EF threw this error because it could not map a field in the View to a property in the POCO of the View.
Not the most helpful error message in this situation IMO.
It may happen when your model is not mapped correctly to your Class. In my case I got this error when I used EF Model First and when I updated my EDMX model from DB but didn't update my Entity class. Specifically a property in Entity was in lower case while in DB and EDMX diagram was in Upper case.
And another issue I had was a model property in EDMX diagram was not converted to my app Enum So that EF couldn't recognize that Entity.
I've been doing database first and using the built in template generation for my models (EF 4.1)
I copied the generated code into a new file and removed the navigation properties. That's when I started to see this error. I have lazy loading turned off, but it appears the navigation properties are still necessary in the POCO's.
I suppose the error might indicate that your model is missing something.
namespace TestApp.BLL
{
using System;
using System.Collections.Generic;
public partial class User
{
public User()
{
//this.Roles = new HashSet<Role>();
}
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
//public virtual ICollection<Role> Roles { get; set; }
}
}
The above code shows the navigation properties commented out. If I uncomment them on all POCO's (that means the Role POCO too) the exception goes away.
UPDATE
This error kept attacking me with various updates I made to the database. Eventually I deleted the edmx file and just created it again with the same tables and stored procs.
Old
I got this when the generated entity was missing a nullable column:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MyProgram.Models
{
using System;
using System.Collections.Generic;
public partial class Question
{
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
public string tags { get; set; }
public int votes { get; set; }//I had to manually add this property which is nullable int in the database
}
}
I added the property after generating the initial model. However, I even tried deleting the table and recreating it. That didn't fix it. Only adding the property manually fixed it for me.
Answering the question is "What are the possible causes of this error?":
This error seems to occur any time the internal/EDMX model is not successfully built, or is not completely built. And there are a large potential number of causes for this problem. It's unfortunate that there seems to be insufficient error reporting or error detection when building the model, so solving it seems to involve trying a bunch of things to see what makes the problem go away.
I ran into another instance of this error over the past few days, using EF 6.0 (currently pre-release code), code-first, and custom conventions. It turns out that the root cause is that I had a custom convention which renames the ID EdmProperty (eg ID -> MyTypeId). If I disabled my custom convention this problem went away; if I enabled my convention the problem occurs. There is no logging or exceptions or other errors to indicate that a problem occurred when the building the model. This exception doesn't rear its head until I try to add an entity to a DbSet. The convention didn't cause any problem when generating the database (via Migrations).
In my scenario I was using EF6 to migrate a MySQL database to MSSQL. I had 2 separate models and contexts, each with their own connection string. The classes had the same name, but the MySQL one was all lowercase and the MSSQL one Pascal casing. I had copied in both connection strings from the relevant assemblies containing my EDMX models. But when I ran my application I got an error about one of the 2 connection strings having been already added to the dictionary list.
So I removed the conflicted entry, foolishly thinking it somehow had access to the connection string in the assembly's own app.config (it's late!). But no, the error was actually happening because both connection strings also had the same name - one all lowercase and one in Pascal casing - i.e. the Dictionary key ignores the casing. So when I removed the MySQL one, it then attempted to use the MSSQL connection string for BOTH models. So I had to re-add, rename and manually set the connection string for the second model in code.
I have a simple class called Applicant. I'm trying to add a template controller using the Entity Framework with Applicant as my model class, and a new data context.
Every time I try to create the controller, I get an error dialog that says "Unable to retrieve metadata for 'MyNameSpace.Models.Applicant'. There was an error generating 'ScaffoldingConnectionFactory'. Try rebuilding your project."
Rebuilding does nothing.
Here is my model class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace MyNameSpace.Models
{
public class Applicant
{
public int ApplicantId { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string MiddleInitial { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public string EmailAddress { get; set; }
[Required]
[DataType(DataType.Date)]
public string DateOfBirth { get; set; }
public virtual Ethnicity Ethnicity { get; set; }
public virtual Race Race { get; set; }
}
public class Ethnicity
{
public int EthnicityId { get; set; }
public string Type { get; set; }
}
public class Race
{
public int RaceId { get; set; }
public string Type { get; set; }
}
}
I feel like I've missed a step but I can't put my finger on it.
I had the same problem and had to fix it similarly.
My version of EF was incompatible with the new MVC tooling. After updating EntityFramework from NuGet, and making a few updates to outdated code, everything is working fine.
This is a terrible answer and I'd like to understand the root cause, but my solution was to uninstall the EntityFramework library package reference from NuGet, then re-install it. Everything works now.
I had the same issue. Tried re-installing EntityFramework using NuGet.
Didn't fix anything.
I'm about to bail and try using Linq.
I thought I had this working earlier!!
http://www.asp.net/mvc/tutorials/creating-model-classes-with-linq-to-sql-cs
Sometimes it seems like the MS stack is always changing so much it's unreliable. Is that why people use Linq?
EDIT: Running web platform installer on MS Visual web designer fixed this problem.
I was just met this problem and then I realize that I have to choose the right one NuGet package to avoid this problem. There are two very familiar packages in the NuGet package list.
The EFCodeFirst.SqlServerCompact is used with Entity Framework Feature CTP5.
The EntityFramework.SqlServerCompact is used with the Entity Framework 4.1.
The "EntityFramework.SqlServerCompact" should be used if you are using Entity Framework 4.1 !!
I got this problem when I tried to create a controller using the "Add Controller" dialog box, and by selecting the "Controller with read/write actions and views, using Entity framework" Template selection.
This generates code for a Controller class. By the way, this includes references to an EntityFramework Context object (such as, in my case for a PersonController, the following line: "Person person = db.People.Find(id);"). This is for a starting point only, and of course you can replace the auto-generated code, if you wish. Either way, this is why it asks for a Context class in the dialog, and why it will auto-gen a new one for you if requested.
I referenced Entity Framework using Nuget, which had the effect of referencing EntityFramework.dll v4.0. I later abstracted out the Data Access code into a different project, so then uninstalled EF through Nuget. There were some existing references to DbSet<> in the Context class, and I think I must have resolved it by getting Resharper to add a reference to get the project simply to get it to compile/build. R# added a reference to System.Data.Entity from the .Net 4 Framework library. It was at this stage that I started getting the error when trying to create new Controllers using the "Controller with read/write actions and views, using Entity framework" template.
I resolved it by (1) removing all references to System.Data.Entity; (2) installing Entity Framework through Nuget and rebuilding; (3) Creating the controller(s); (4) uninstalling EF through Nuget, removing the auto-generated Context class and replacing the autogenerated code in the controller with my own that referenced my classes from my DAL project/assembly.
Had same problem. Problem is that the context is in separate assembly.
namespace WebJhs179.Models {
/// <summary>
/// This class is just wrapper to actual context. Because actual context is in separate assembly,
/// MVC3's controller creation fails.
/// Workaround: Create empty class and inherit actual context.
/// </summary>
public class Jhs179Context : Jhs179.Jhs179DbContext {
}
}
I had the same problem while adding new controller in ASP.NET MVC 4, I solved the problem by moving the Database.SetInitializer(new SomeDataContextInitializer()); from the constructor of the DBContext to Application_Start method in Global.asax.cs.
Hope it helps.
Can it be that the tools expect your Entity Framework EDMX to be in the same assembly as your website?
I've had the same error occuring in a project where the EDMX was in a separate assembly.
This was nessesary because we needed database access for a website as well as for a service.
I had the same problem using EF 4.3.1. In my case it was because I had attached extra functionality to the generated DbContext using a partial class. When I removed this class from the model project, the scaffolding worked correctly.
In my case the .edmx and model classes were in a separate assembly. This was not the issue, as I was able to get the scaffolding to work correctly simply be removing a partial class that I had used to extend the generated DbContext class.
I was trying to use MVC 4 and Entity Framework 6. I finally figured out that MVC4 references the EF5 dll by default, uninstalled and installed EF6. They I got the message:
MVC Scaffolding does not support Entity Framework 6 or later. For
more information please visit:
[http://go.microsoft.com/fwlink/?LinkId=276833][1]
Solution was to use MVC 5 instead, as I had already written EF6 code, and the MVC app was new.