I have the following two entities refering to one table using split table option from EF Core - this very simplified version:
class Account
int Id
Settings Settings
class Settings
int AccountId (maps to Id)
string PropertyX
From the documentation:
If all of the columns used by a dependent entity are NULL in the
database, then no instance for it will be created when queried. This
allows modeling an optional dependent entity, where the relationship
property on the principal would be null. Note that this would also
happen if all of the dependent's properties are optional and set to
null, which might not be expected.
Is it possible to disable this behaviour? I have multiple columns with a lot of grouped behaviour that are default null.
Now the entity (Settings) won't be created by default. This means I have to nullcheck everywhere. I rather have Settings created with null values for all properties.
If I create the instance myself in the constructor of the parent entity (Account) the changes don't seem to be tracked, because I guess EF Core is not aware of the class.
Any solution?
Unfortunately this functionality is not available in EF Core 3.
The so called required dependent has been added in EF Core 5.0 - Required 1:1 dependents:
In EF Core 3.1, the dependent end of a one-to-one relationship was always considered optional. This was most apparent when using owned entities, as all the owned entity's column were created as nullable in the database, even if they were configured as required in the model.
In EF Core 5.0, a navigation to an owned entity can be configured as a required dependent
The above is just the announcement of the feature inside What's New section. In fact it can be used for any one-to-one relationship, as mentioned in the official One-to-one documentation section:
The dependent side is considered optional by default, but can be configured as required. However EF will not validate whether a dependent entity was provided, so this configuration will only make a difference when the database mapping allows it to be enforced. A common scenario for this are reference owned types that use table splitting by default
To configure the dependent as required, you have to use the Navigation fluent API (also introduced in 5.0) combined with IsRequired:
modelBuilder.Entity<Account>()
.Navigation(e => e.Settings)
.IsRequired();
Related
First of all I hope this question is allowed because I guess its a rather framework-specific question (Symfony). I am running into the following problem:
A form is submitted and checked for validity for creating a new 'Toernooionderdeel' and as a result the Persist and Flush operations of Doctrine for this Entity are to be called attempting to put the newly created entity into the database. Fairly basic stuff to this point. But the form fails at ->isValid() before persisting and flushing can commence.
In my case the Constraints are applied on properties in various ways through annotation.
#Assert\Valid specifically is used on properties that define ManyToOne relationships with other entities and it all works fine, until...
I attempt to use #Assert\Valid on a property of 'Toernooionderdeel' called '$toernooi' which represents a ManyToOne relationship (Toernooionderdeel -> Toernooi).
The difference between this one and the other relationships I validate in the same way is that this 'Toernooi' Entity is derived from another entity, where the other entities aren't.
Despite obviously having a 'Toernooi' defined under the '$toernooi' property of 'Toernooionderdeel', the Constraint detects it as a violation and thus the form doesnt pass validation.
What things do i have to consider when doing this type of validation (using Constraints) on an 'advanced' entity construction like this? Has any of you done this before and if so, how did you do it?
When the entity referenced in a property ("child") is validated in the parent object via Assert\Valid, it's validity is also checked. When the child entity isn't valid, the parent isn't valid either (transitive).
After release of EF Core 2.2 it is now possible to have both single and collection values of owned types.
In contrast to classical navigational properties owned types are always included in the entity, so owned types looks like a natural way of describing the shape of an aggregate.
Are there any DDD related use cases where classical navigation properties are still better?
Update 1
Prior to 2.2 I was able to call modelBuilder.Entity<OwnedType> and configure alternative key.
Now with 2.2 I started getting errors during migration: primary key is not defined for the entity. However, ReferenceOwnershipBuilder class which is passed as a parameter to buildAction lambda in method OwnsOne does not contain HasAlternateKey. This is currently a known limitation.
Update 2
Currently owned types do not support inheritance. This may be critical for some use cases.
I implemented Windows Identity into my application and using EF Migrations the appropriate [AspNet*] tables were added to my database. As typical in this scenario, I created an ApplicationUser class that inherits from IdentityUser. My 'ApplicationUser' class does not have any additional properties. And at that point in time I did not touch any code or classes related to Roles.
Now I am looking to add roles so I followed the same pattern as before. I created an 'ApplicationRole' class that inherits from 'IdentityRole' but did not add any addition properties.
However, and this is where my question comes in, EF migrations is trying to create a [Discriminator] column for the AspNetRoles table. Yet it never created one for the AspNetUsers table in the previous migration.
I understand the purpose of the Discriminator column so I am not questioning why it is there. I just do not understand why it is adding it for one table and not the other when both base classes were inherited by the "application" equivalent classes.
The only plausible reason I can think of is because the original IdentityRole class was used in the earlier migration and now I am trying to add a new migration that uses the base class. If so, is there a way to get EF to ignore this? There are no plans to ever create multiple classes that inherit from the base nor will I be using the base directly so the Discriminator will always contain the same value.
Using EF with MVC4 allows you to specify the inclusion of Foreign Key columns in the model. While this not normally part of OR modeling, it does allow MVC4 to automatically generate views with dropdown lists, for the foreign key relationships, when you generate a controller with the MVC controller with read/write actions and views, using Entity Framework option.
I have hit a problem creating an object in this scenario.
Greatly simplified, the models in question are:
Questionnaire:
QuestionnaireID: PK
CandidateId: FK
Candidate: Associated object
Candidate:
CandidateID: PK
Name: string
The problem I have hit is that on a Create view post-back to create a new Questionnaire ModelState.IsValid is false. On investigation the error listed is The parameter conversion from type 'System.String' to type 'Data.Candidate' failed because no type converter can convert between these types.
ModelState.Keys includes Questionnaire.Candidate as well as Questionnaire.CandidateId (which is valid).
I am sure this is something simple, but would like to hear some solutions. The viewbag only has a set for the drop-down list and the view has an #model of type #model Data.Questionnaire. There are no editor fields bound to Questionnaire.Candidate..
As I have no idea why the built-in EF models do not like the MVC generated scaffolding, for Create postbacks with foreign key columns enabled, I have reverted to what is a more secure solution (still happy to hear why it fails out-of-the-box):
Create individual view models for specific sensitive operations like create
The theory goes that there are a number of problems using EF domain entities as viewmodels including:
They potentially expose too much information or allow additional fields to be posted back
Validation text is an interface concern and should not be part of a the data model (they actually suggest even the viewmodel is not the place for this text, but I digress).
So basically I now have a CreateCandidateQuestionnaireVM class with only the required fields for selecting appropriate values for a new instance.
I'm migrating from Linq-to-SQL to Entity Framework (4.4), using Database First with a DbContext. I'm wondering whether the following behavior is normal:
using (var e = new AgendaEntities()) {
var store = e.Stores.First();
var office = e.Offices.Create();
office.Store = store; // Set association
Console.WriteLine(office.StoreID); // shows Guid.Empty, expected store.ID!
}
In L2S, setting the Store association to an entity would also update the StoreID key. In EF, this doesn't seem to be happening. This is regardless of whether the entities are new or loaded from the context.
When I SaveChanges, it saves correctly and the StoreID is updated to match office.ID, but why does this only happen after the save?
Is there something I'm missing, or am I now supposed to keep foreign keys in sync manually?
Solution Edit:
This is called property fixup, and used to be done automatically by the generated proxies. However, with DbContext this is no longer the case. According to this Connect issue, this is by design.
Hello,
The DbContext template actually doesn't generate classes that will be used as change tracking proxies - just lazy loading proxies (which don't do fix-up). We made this decision because change tracking proxies are complex and have a lot of nuances that can be very confusing to developers.
If you want fix-up to occur before SaveChanges you can call myContext.ChangeTracker.DetectChanges.
~EF Team
An alternative is to call DbContext.Entry(entity), which will sync up the entity. This is described in this article: Relationships and Navigation Properties under "Synchronizing the changes between the FKs and Navigation properties"
No. Entity framework does this for you. Read Relationships and Navigation Properties for more information.
By assigning a new object to a navigation property. The following
code creates a relationship between a course and a department.
If the objects are attached to the context, the course is also
added to the department.Courses collection, and the
corresponding foreign key property on the course object is set to the
key property value of the department.
course.Department = department;
But as you observed, this only happens after you call SaveChanges or one of the other actions mentioned in the "Synchronizing the changes between the FKs and Navigation properties" portion of the document linked above.
If you are using POCO entities without proxies, you must make sure
that the DetectChanges method is called to synchronize the related
objects in the context. Note, that the following APIs automatically
trigger a DetectChanges call.
DbSet.Add
DbSet.Find
DbSet.Remove
DbSet.Local
DbContext.SaveChanges
DbSet.Attach
DbContext.GetValidationErrors
DbContext.Entry
DbChangeTracker.Entries
Executing a LINQ query against a DbSet
If this is not happening at all, my guess is that you haven't properly defined StoreID as the foreign key of the navigation property Store.