I am having some strange issues, I am attempting to pull a record out of the database and it seems like most of it is null even know if I manually look in the DB it's populated.
Model
public class AdminConfiguration : Entity // Entity is an abstract class containing an ID
{
public bool Authentication { get; set; }
public List<ApplicationConfiguration> ApplicationConfiguration { get; set; }
public List<LinksConfiguration> LinksConfiguration { get; set; }
public EmailConfiguration EmailConfiguration { get; set; }
public bool WakeOnLan { get; set; }
}
Basically any reference to another class is null The only thing that is populated is the WakeOnLan property.
Query
public AdminConfiguration Find(int id)
{
return Db.AdminConfiguration.Find(id);
}
I have a feeling I have a misunderstanding regarding how I set up the models. I am expecting the query to return me a fully populated AdminConfiguration object.
Try to set navigation properties as virtual to enable lazy loading:
public virtual List<ApplicationConfiguration> ApplicationConfiguration { get; set; }
Please refer to https://msdn.microsoft.com/en-us/data/jj193542.aspx
This enables the Lazy Loading feature of Entity Framework. Lazy
Loading means that the contents of these properties will be
automatically loaded from the database when you try to access them.
The best way to setup your model is:
public class AdminConfiguration : Entity // Entity is an abstract class containing an ID
{
public AdminConfiguration()
{
this.ApplicationConfigurations = new HashSet<ApplicationConfiguration>();
this.LinksConfigurations = new HashSet<LinksConfiguration>();
}
public bool Authentication { get; set; }
public EmailConfiguration EmailConfiguration { get; set; }
public bool WakeOnLan { get; set; }
// Navigation properties
public virtual ICollection<ApplicationConfiguration> ApplicationConfigurations { get; set; }
public virtual ICollection<LinksConfiguration> LinksConfigurations { get; set; }
}
Related
I have a very basic EF setup that is throwing an odd error when trying to populate a navigation property by using .Include. Here are the entity Models:
public class LineGroup
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public ICollection<LineGroupMember> LineGroupMembers { get; set; }
}
public class LineGroupMember
{
public int ID { get; set; }
public int Extension { get; set; }
public string Name { get; set; }
public int Permissions { get; set; }
public bool IsLoggedIn { get; set; }
public int LineGroupID { get; set; }
internal LineGroup LineGroup { get; set; }
}
I am using these through an injected DB context, and can query each just fine without using navigation properties. I can also query the LineGroups and include the LineGroupMembers property just fine, like so:
var LineGroups = _context.LineGroups.Include(l => l.LineGroupMembers).ToList();
This load all of the line groups into a list that has a correctly working "LineGroupMembers" collection for each Line Group. However, if I try
var lineGroupMembers = _context.LineGroupMembers.Include(m => m.LineGroup).ToList();
I get "NullReferenceException" with no helpful details. Any ideas why the navigation property will work one way and not the other? There are no null values in either database table...
Make your navigation property public
public LineGroup LineGroup { get; set; }
If it is internal it won't be picked up by default by EF. You could also add explicit fluent mapping to force EF to recognize it as well.
I created an inheritance hierarchy after a few migrations. Now when I update the database using code first migrations, code-first is not automatically creating the discriminator field. I have since dropped the table and recreated it (using code-first migrations) without any luck. The only thing I can think of is that there are no additional "non-virtual" properties in the derived classes--the inheritance structure was created to enforce a business rule that only a certain derived type can have a relationship with another entity.
Base Type:
public abstract class Process
{
private ICollection<ProcessSpecification> _specifications { get; set; }
protected Process()
{
_specifications = new List<ProcessSpecification>();
}
public Int32 Id { get; set; }
public String Description { get; set; }
public Int32 ToolId { get; set; }
public virtual Tool Tool { get; set; }
public virtual ICollection<ProcessSpecification> Specifications
{
get { return _specifications; }
set { _specifications = value; }
}
}
Derived class (no different/unique scalar properties):
public class AssemblyProcess : Process
{
private ICollection<AssemblyProcessComponent> _components;
public AssemblyProcess()
{
_components = new List<AssemblyProcessComponent>();
}
public virtual ICollection<AssemblyProcessComponent> Components
{
get { return _components; }
set { _components = value; }
}
}
Another derived type
public class MachiningProcess : Process
{
private ICollection<MachiningProcessFeature> _features;
public MachiningProcess()
{
_features = new List<MachiningProcessFeature>();
}
public virtual ICollection<MachiningProcessFeature> Features { get { return _features; } set { _features = value; } }
}
Is code-first not adding the discriminator column in the database because it doesn't see any differences between the derived classes (because of there not being any unique "non-virtual" properties)? If so, how do I get around this? If not, what are some reasons why code-first would not automatically create the discriminator column in the database? I have another TPH structure that works exactly the way it's supposed to.
DbContext:
public LineProcessPlanningContext()
: base("LineProcessPlanning")
{
}
public DbSet<Component> Components { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Feature> Features { get; set; }
public DbSet<OperationDefinition> OperationDefinitions { get; set; }
public DbSet<PartDesign> PartDesigns { get; set; }
public DbSet<Process> Processes { get; set; }
public DbSet<ProcessPlan> ProcessPlans { get; set; }
public DbSet<ProcessPlanStep> ProcessPlanSteps { get; set; }
public DbSet<ProductionLine> ProductionLines { get; set; }
public DbSet<StationCycleDefinition> StationCycleDefinitions { get; set; }
public DbSet<StationCycleStep> StationCycleSteps { get; set; }
public DbSet<StationDefinition> StationDefinitions { get; set; }
public DbSet<UnitOfMeasurement> UnitsOfMeasurement { get; set; }
public DbSet<Tool> Tools { get; set; }
I also tried creating "dummy" properties that are unique to each derived type. Code migrations added the new properties as columns to the table, but the migration did not create a discriminator column.
I figured out the cause of this in my situation, same as yours. The base class is abstract, therefore EF won't create a TPH table for that class since it can't be instantiated. As a result of the abstract base class, EF will create tables for each of the derived classes, and therefore no need for a discriminator column.
In my case, it was acceptable to remove abstract from the base class. Once I did this, EF's TPH worked as expected.
I'm creating a EF5 entity model with the designer (VS2012), and used the EF5 DbContext generator as code generation item.
My model contains an entity deriving from another (not abstract).
So let's say the base entity is called BaseEntity, and the derived entity is DerivedEntity.
Now I see in the generated context class, that there is no
Public DbSet<DerivedEntity> DerivedEntities { get; set; }
defined.
Only
Public DbSet<BaseEntity> BaseEntities { get; set; }
is defined.
Is this normal ? And if yes, how do I query the derived entities in linq ?
I'm used to query like this:
using(var ctx = new EntityContainer)
{
var q = from e in ctx.DerivedEntities <-- but this is now not possible since it doesn't exist
select e;
return q.ToList();
}
Thanks for replying.
EDIT:
As requested, generated classes posted:
public partial class Scheduling
{
public int Id { get; set; }
public string Subject { get; set; }
public System.DateTime BeginDate { get; set; }
public System.DateTime EndDate { get; set; }
}
public partial class TeamScheduling : Scheduling
{
public int TeamId { get; set; }
public Nullable<int> AssignmentId { get; set; }
public virtual Team Team { get; set; }
public virtual Assignment Assignment { get; set; }
}
public partial class EntityContainer : DbContext
{
public EntityContainer()
: base("name=EntityContainer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Team> Teams { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<Assignment> Assignments { get; set; }
public DbSet<ProductType> ProductTypes { get; set; }
public DbSet<AssignmentPreference> AssignmentPreferences { get; set; }
public DbSet<Scheduling> Schedulings { get; set; }
}
As you see, the EntityContainer class does not contain
public DbSet<TeamScheduling> TeamSchedulings { get; set; }
This is expected when you use inheritance the way you have. context.Schedulings contains both Scheduling objects and TeamScheduling objects. You can get the TeamScheduling objects only by asking for context.Schedulings.OfType<TeamScheduling>(). Note that you cannot meaningfully use context.Schedulings.OfType<Scheduling>() to get the others: that will also include the TeamScheduling objects.
You could alternatively try context.Set<TeamScheduling>(), but I'm not entirely sure that will work.
If your intention is to have two tables come up, say a parent Scheduling entity as well as a child TeamScheduling entity that has a foreign key back to the Scheduling entity, consider using a Table-per-Type (TPT) mapping as discussed here.
In essence, you should modify your "OnModelCreating" method to have the following code:
modelBuilder.Entity<TeamScheduling>().ToTable("TeamScheduling");
This explicitly tells EF that you want to have the TeamScheduling subclass to be represented as its own table. Querying it via LINQ would be simple as you would be able to do something like the following:
var teamScheds = context.Set<TeamScheduling>().Where(s => s.Id == 1).FirstOrDefault();
I just started prototyping our existing object model in entity framework/code first and hit my first snag. Unfortunately the documentation for this seems to be very scarce.
My key is not a primitive but an object that wraps a primitive. How do I get this to work with EF/Code first:
public class EFCategoryIdentity
{
public string IdentityValue { get; private set; }
public EFCategoryIdentity(string value)
{
IdentityValue = value;
}
}
public class EFCategory
{
[Key]
public EFCategoryIdentity CategoryIdentity { get; set; }
public string Name { get; set; }
public virtual ICollection<EFProduct> Products { get; set; }
}
public class EFProduct
{
[Key]
public int ProductId { get; set; }
public string Name { get; set; }
public virtual EFCategory Category { get; set; }
}
What do I need to put here to make this work?
public class MyTestContext : DbContext
{
public DbSet<EFCategory> Categories { get; set; }
public DbSet<EFProduct> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EFCategory>()
.// Help!
}
}
Thanks!
Entity framework can use only primitive types as keys. Every time you wrap some mapped property to separate type you are creating complex type. Complex types have some limitation
They cannot be keys
They cannot contain keys
They cannot contain navigation properties
etc.
I have the following class
class MCustomer : DomanEntity
{
public MCustomer()
{
}
public virtual iCustomerEntity CustomerDetials { get; set; }
public virtual SolicitationPreferences SolicitationPreferences { get; set; }
}
public interface iCustomerEntity
{
Contact Contact { get; set; }
}
public class PersonEntity: DomanEntity, iCustomerEntity
{
public PersonEntity()
{
Intrests = new List<Intrest>();
Children = new List<PersonEntity>();
}
public virtual Contact Contact { get; set; }
public virtual DateTime BirthDate { get; set; }
public virtual IList<Intrest> Intrests { get; set; }
public virtual PersonEntity Spouse { get; set; }
public virtual IList<PersonEntity> Children { get; set; }
}
When I use fluent NHibernate AutoMapping I receive this error:
NHibernate.MappingException: An association from the table MCustomer refers to an unmapped class: Calyx.Core.Domain.CRM.iCustomerEntity
How do I set up a property in my domain model that has an Interface type?
I don't think, that you can do that.
When you would try to load your MCustomer (session.Load<MCustomer>(id)), NHibernate would only know, that you want to get MCustomer, that has an iCustomerEntity. It would not know which implementation (PersonEntity or CoderEntity?) to use. How would it know which mapping to use to retrieve the data for iCustomerEntity?
https://www.hibernate.org/hib_docs/nhibernate/html/inheritance.html
Its a standard Nhibernate pattern. I'm trying to do the same thing
Looks like a "any" mapping to me. You should look into that. And as far as I can see FNH does not support that yet.