Ef4 Code First: How to Add a Relationship Without Adding a Navigation Property

EF4 Code First: how to add a relationship without adding a navigation property

I believe you always need navigation property on at least one side when using code-first. Then you will be able to map it:

public class User  
{
public string UserId { get; set; }
public string PasswordHash { get; set; }
public bool IsDisabled { get; set; }
public DateTime AccessExpiryDate { get; set; }
public bool MustChangePassword { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
}

public class Role
{
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}

public class Right
{
public Guid RightId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
}

public class TestContext : DbContext
{
public TestContext() : base("Entities")
{}

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

modelBuilder.Entity<User>()
.HasRequired(r => r.Role)
.WithMany()
.HasForeignKey(r => r.RoleId);

modelBuilder.Entity<Right>()
.HasRequired(r => r.Role)
.WithMany()
.HasForeignKey(r => r.RoleId);
}
}

How do I setup a foreign key relationship in codefirst without using a navigation property?

You always need navigation property on at least one side to build a relation. If you don't have navigation properties you have nothing to bind your your foreign key with and it will remain as common column.

How do i create One-to-One to relationship without having navigation property in dependent entity

To create a one-to-one relationship without a navigation property on the dependent side, you'll need to use the fluent API. For example, in your DbContext class, you can override OnModelCreating and use this to define the relationship:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// I'm assuming the report is optional
modelBuilder.Entity<Student>()
.HasOptional(t => t.StudentReport)
.WithRequired();
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
}

See documentation for WithRequired() here

EF Code First foreign key without navigation property

With EF Code First Fluent API it is impossible. You always need at least one navigation property to create a foreign key constraint in the database.

If you are using Code First Migrations you have the option to add a new code based migration on the package manager console (add-migration SomeNewSchemaName). If you changed something with your model or mapping a new migration will be added. If you didn't change anything force a new migration by using add-migration -IgnoreChanges SomeNewSchemaName. The migration will only contain empty Up and Down methods in this case.

Then you can modify the Up method by adding the follwing to it:

public override void Up()
{
// other stuff...

AddForeignKey("ChildTableName", "ParentId", "ParentTableName", "Id",
cascadeDelete: true); // or false
CreateIndex("ChildTableName", "ParentId"); // if you want an index
}

Running this migration (update-database on package manage console) will run a SQL statement similar to this (for SQL Server):

ALTER TABLE [ChildTableName] ADD CONSTRAINT [FK_SomeName]
FOREIGN KEY ([ParentId]) REFERENCES [ParentTableName] ([Id])

CREATE INDEX [IX_SomeName] ON [ChildTableName] ([ParentId])

Alternatively, without migrations, you could just run a pure SQL command using

context.Database.ExecuteSqlCommand(sql);

where context is an instance of your derived context class and sql is just the above SQL command as string.

Be aware that with all this EF has no clue that ParentId is a foreign key that describes a relationship. EF will consider it only as an ordinary scalar property. Somehow all the above is only a more complicated and slower way compared to just opening a SQL management tool and to add the constraint by hand.

Entity Framework: Map Foreign Key without Navigation Property?

Navigation property is primary construct whereas foreign key is helper (imho wrong helper). EF recognizes ordering of DB commands by relationships which are defined by navigation properties. You cannot define relation just by foreign key. You need navigation property on at least one side of the relation.

Map Many to Many relationship without navigation property

You can and this case must define the many-to-many relationship with Fluent API:

modelBuilder.Entity<User>()
.HasMany(u => u.StarredWidgets)
.WithMany() // <- no parameter here because there is no navigation property
.Map(m =>
{
m.MapLeftKey("UserId");
m.MapRightKey("WidgetId");
m.ToTable("UserWidgets");
});

Entity Framework 6 Code First Foreign Key Without Corresponding Properties

To create a relationship in Code First you need to have at least a navigation property in one of both ends (this kind of relationship are called unidirectional relationships). A typical one to one relationship is configured as follow:

public class User
{
public User()
{
}

[Key]
[Column("ID", TypeName ="nvarchar(128)")]
public string ID { get; set; }

public string Name{ get; set; }

public virtual UserSetting UserSetting {get;set;}
}

public class UserSetting
{
public UserSetting()
{
}

[Key,ForeignKey("User"),Column("UserID")]
public string ID { get; set; }

//...

public virtual User User{get;set;}
}

Now, with this model you aren't adding any new column to your tables, it's going to be the same, only now you're configuring the PK of UserSettings table as FK of the relationship (what you are trying to achieve).

Now, as I said EF needs at least one navigation property to create the relationship. So, if you want, you can delete the UserSetting nav. property on User, that's ok, leaving the data annotations over the Id of UserSetting and the User navigation property is enough to Code First to create the relationship.



Related Topics



Leave a reply



Submit