Entity Framework Model First 1:0..1 Relationship - visual-studio-2012

I created the following model in the Entity Framework 5 Model Designer in Visual Studio 2012:
Then I generated the database from the model, which resulted in the following tables in my database:
Please help me understand why Entity Framework is generating a one-to-many relationship for a one-to-zero-or-one association.
Update #1
Furthermore, if I change the association from 1:0..1 to 1:1 like this:
Then not only is there still no one-to-one relationship in the database, but now the one-to-many relationship is flipped around, which seems even more weird to me:
Update #2
In response to Mystere Man's comment and answer, the structure I'm expecting to see in SQL Server, which is a valid 1:0..1 relationship is as follows:
Furthermore, I am able to get this working exactly as intended with the following Code First fluent mapping:
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
ToTable("Users");
HasKey(t => t.UserId);
Property(t => t.UserId)
.HasColumnName("UserId");
Property(t => t.Name)
.HasColumnName("Name")
.IsRequired()
.HasMaxLength(50);
Property(t => t.EmailAddress)
.HasColumnName("EmailAddress")
.IsRequired()
.HasMaxLength(254);
Property(t => t.CreatedDateTime)
.HasColumnName("CreatedDateTime");
HasOptional(t => t.Subscription)
.WithRequired(t => t.User);
}
}
public class SubscriptionMap : EntityTypeConfiguration<Subscription>
{
public SubscriptionMap()
{
ToTable("Subscriptions");
HasKey(t => t.SubscriptionId);
Property(t => t.SubscriptionId)
.HasColumnName("SubscriptionId");
Property(t => t.TypeValue)
.HasColumnName("TypeValue");
Property(t => t.CreatedDateTime)
.HasColumnName("CreatedDateTime");
Property(t => t.ExpiresDateTime)
.HasColumnName("ExpiresDateTime");
HasRequired(t => t.User)
.WithOptional(t => t.Subscription);
}
}
So, I know it's possible to achieve this behavior with Code First Entity Framework. My question is why it's not possible to do it with the Model First approach.
What's going on here and why?
Thanks!

SQL does not have a way to define a true 1:1 or 1:0..1 data model, except when both entities have the same primary key. Even so, you can't have a 1:1 because you can't insert records into more than one table in a single statement, so the data model has to allow 1:0..1 by virtue of there being a intermediate state where one record will exist without the other.
The only way to do this in SQL is to do exactly what EF is doing here, create a 1:*, and then impose constraints ensure uniqueness (such as a Unique Constraint). However, EF doesn't support constraints (you would have to create them manually) so it's possible to insert more than one record and violate your model.
EDIT:
Since you've clarified that you're talking about Model First, and that you are looking for a shared primary key, then here's what you have to do.
Right click on the Association, and create a referential constraint between Subscription and User. This will then cause EF to generate the 1:0..1 relationship you are looking for.

Related

How can we populate (or load) a 1:1 relationship from inside a entity class in MikroORM?

just some quick background: We have a Menu entity which has a 1:1 with MenuActiveHours entity. The MenuActiveHours holds information regarding the time the Menu is to be active throughout all 7 days of the week.
{
"monday": "1200-1400",
"tuesday": "",
...
]
And the Menu entity has a "status" property which is not persisted and it is calculated by checking if there is any day it has some hours active.
In the Menu.entity.ts we have:
#Property({
persist: false,
})
get status() {
if(this.activeHours) {
return
this.activeHours.getActiveHoursAsArray().filter((day) => day.hours != "").length > 0 ? MENU_BUILDER_STATUS.ACTIVE : MENU_BUILDER_STATUS.NOT_ACTIVE
}
return "No status given"
}
This works fine if the entity of "activeHours" is actually populated. But its not, and in our case we cant populate it in the service either. So for example if it was a 1:M we could just .loadItems() and then getitems() and it loads it but i cant seem to figure out how to load the 1:1 inside the entity.
Easily put: How can we load a 1:1 relationship inside a function inside a entity? And am i trying to set the status from a wrong point of view and should maybe use something like intercepters instead?
Loading things is async operation, so you can't do that from inside a getter.
To load an entity you can do wrap(entity).init(). Alternatively, you can also use Reference wrapper which has load() method.
https://mikro-orm.io/docs/entity-references#better-type-safety-with-referencet-wrapper

How can I eager fetch content of custom types in a ContentManager query?

I'm running into some n+1 performance issues when iterating over a collection of ContentItems of a custom Type that I created solely through migrations.
ContentDefinitionManager.AlterPartDefinition("MyType", part => part
.WithField("MyField", field => field
...
)
);
ContentDefinitionManager.AlterTypeDefinition("MyType", type => type
.WithPart("MyType")
);
Every time I access a field of this part a new query is performed. I can use QueryHints to avoid this for the predefined parts
var myItems = _orchardServices.ContentManager.Query().ForType("MyType")
.WithQueryHints(new QueryHints().ExpandParts<LocalizationPart()
...
);
but can I do this for the ContentPart of my custom type too? This does not seem to work:
var myItems = _orchardServices.ContentManager.Query().ForType("MyType")
.WithQueryHints(new QueryHints().ExpandParts<ContentPart>()
...
);
How can I tell Orchard to just get everything in one go? I'd prefer to be able to do this without writing my own HQL or directly addressing the repositories.
Example:
var myItems = _orchardServices.ContentManager.Query().ForType("MyType");
#foreach(var item in myItems.Take(100)) {
foreach(var term in item.Content.MyItem.MyTaxonomyField.Terms) {
// Executes 100 queries
<div>#term.Name</div>
}
}
TaxonomyField doesn't store ids and using the TaxonomyService inside of the loop wouldn't improve performance. Right now, to work around this, I fetch all TermContentItems.Where(x => myItems.Select(i => i.Id).Contains(TermPartRecord.Id)) from the repository outside of the loop as well as a list of all the terms of the Taxonomy that the field is using. Then inside the loop:
var allTermsInThisField = termContentItems.Where(tci => tci.TermsPartRecord.Id == c.Id)
.Select(tci => terms.Where(t => t.Id == tci.TermRecord.Id).Single()).ToList()
I'm not a very experienced programmer but this was the only way I could see how to do this without digging into HQL and it seems overly complicated for my purposes. Can Orchard do this in less steps?

Fluent NHibernate - Multiple collections in the same table

Im working on rebuilding a clients software and they want to keep their database as unmodified as possible.
I got a table where they collect users and orders for different companies, no biggie there but the twist is they do it for multiple entities.
for example the table looks like this:
ID
UserID
Index
CompanyID
Type
lets say they got entities like Project and Workflow, then the Type column would be 'P' for projects and 'W' for workflows. So on a ID is the ID of a Project or Workflow Identity. UserID is always a foreign key to a User entity and Index is the order that the user is used when this Project/Workflow is used. And CompanyID is what company owns project or workflow entity.
I have tried to search google for this but i came up with nothing.
What i want is on a Template entity map two collections say StandardProjectUsers and StandardWorkflowUsers and they should collect them from correct entities with a user and index for current company.
Is this at all possible with fluent nhibernate ?
A nice article on how to do it: http://www.philliphaydon.com/2011/08/fluent-nhibernate-table-inheritance-discriminators/
You are looking at a table-per-hierarchy strategy.
In a nutshell you use:
public class BaseClassMap : ClassMap<BaseClass>
{
public BaseClassMap()
{
DiscriminateSubClassesOnColumn("Type");
...
}
}
public class WorkflowMap : SubclassMap<Workflow>
{
public WorkflowMap()
{
DiscriminatorValue("W");
...
}
}
public class ProjectMap : SubclassMap<Project>
{
public ProjectMap()
{
DiscriminatorValue("P");
...
}
}

Filtering navigation property in eager loading

I have been working with soft delete and now i want to load the navigation properties of my entity that are not "deleted". I have found a way, my problem this way is not to clear for me, there is another way to do this.
Context.CreateSet().Include("Salary").Select(u => new {User= u, Salary = u.Salarys.Where(s => !s.Deleted)}).AsQueryable().Select(a => a.User).AsQueryable();
Eager loading doesn't support filtering. Your code can be simplified to:
var users = Context.CreateSet<User>()
.Select(u => new {
User = u,
Salary = u.Salaries.Where(s => !s.Deleted)
})
.AsEnumerable()
.Select(a => a.User);
Include is not needed because you are replacing it with your own query and AsQueryable is not needed because the query is IQueryable all the time till called AsEnumerable which will sqitch to Linq-to-Objects when selecting users and selected salaries. EF will take care of correctly fixing navigation properties for you.

Kohana ORM Relationships

I have a couple of tables and have defined relationships for them.
{Table Department} {Table Unit} {Table Branch}
A Department can have more than one branch, a branch can only belong to one department. I need to be able to get the department name, departmentid, branchname
Branch has an instance of departmentid in it.
How do I pull this in one ORM call?
class Model_Admin_Departments extends ORM
{
protected $_has_many = array('branches' => array ());
class Model_Admin_Branches extends ORM
{
protected $_belongs_to = array('departments ' => array());
I have also created the foreign key constraints on the db side with action cascade on delete. Could this cause problems or that is fine?
Assuming you have the right relationships declared you should be able to use the with(...) method on your ORM object.

Resources