One to one optional relationship using Entity Framework Fluent API - c#

We want to use one to one optional relationship using Entity Framework Code First. We have two entities.
public class PIIUser
{
public int Id { get; set; }
public int? LoyaltyUserDetailId { get; set; }
public LoyaltyUserDetail LoyaltyUserDetail { get; set; }
}
public class LoyaltyUserDetail
{
public int Id { get; set; }
public double? AvailablePoints { get; set; }
public int PIIUserId { get; set; }
public PIIUser PIIUser { get; set; }
}
PIIUser may have a LoyaltyUserDetail but LoyaltyUserDetail must have a PIIUser.
We tried these fluent approach techniques.
modelBuilder.Entity<PIIUser>()
.HasOptional(t => t.LoyaltyUserDetail)
.WithOptionalPrincipal(t => t.PIIUser)
.WillCascadeOnDelete(true);
This approach didn't create LoyaltyUserDetailId foreign key in PIIUsers table.
After that we tried the following code.
modelBuilder.Entity<LoyaltyUserDetail>()
.HasRequired(t => t.PIIUser)
.WithRequiredDependent(t => t.LoyaltyUserDetail);
But this time EF didn't create any foreign keys in these 2 tables.
Do you have any ideas for this issue?
How can we create one to one optional relationship using entity framework fluent api?

EF Code First supports 1:1 and 1:0..1 relationships. The latter is what you are looking for ("one to zero-or-one").
Your attempts at fluent are saying required on both ends in one case and optional on both ends in the other.
What you need is optional on one end and required on the other.
Here's an example from the Programming E.F. Code First book
modelBuilder.Entity<PersonPhoto>()
.HasRequired(p => p.PhotoOf)
.WithOptional(p => p.Photo);
The PersonPhoto entity has a navigation property called PhotoOf that points to a Person type. The Person type has a navigation property called Photo that points to the PersonPhoto type.
In the two related classes, you use each type's primary key, not foreign keys. i.e., you won't use the LoyaltyUserDetailId or PIIUserId properties. Instead, the relationship depends on the Id fields of both types.
If you are using the fluent API as above, you do not need to specify LoyaltyUser.Id as a foreign key, EF will figure it out.
So without having your code to test myself (I hate doing this from my head)... I would translate this into your code as
public class PIIUser
{
public int Id { get; set; }
public LoyaltyUserDetail LoyaltyUserDetail { get; set; }
}
public class LoyaltyUserDetail
{
public int Id { get; set; }
public double? AvailablePoints { get; set; }
public PIIUser PIIUser { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<LoyaltyUserDetail>()
.HasRequired(lu => lu.PIIUser )
.WithOptional(pi => pi.LoyaltyUserDetail );
}
That's saying LoyaltyUserDetails PIIUser property is required and PIIUser's LoyaltyUserDetail property is optional.
You could start from the other end:
modelBuilder.Entity<PIIUser>()
.HasOptional(pi => pi.LoyaltyUserDetail)
.WithRequired(lu => lu.PIIUser);
which now says PIIUser's LoyaltyUserDetail property is optional and LoyaltyUser's PIIUser property is required.
You always have to use the pattern HAS/WITH.
HTH and FWIW, one to one (or one to zero/one) relationships are one of the most confusing relationships to configure in code first so you are not alone! :)

Just do like if you have one-to-many relationship between LoyaltyUserDetail and PIIUser so you mapping should be
modelBuilder.Entity<LoyaltyUserDetail>()
.HasRequired(m => m.PIIUser )
.WithMany()
.HasForeignKey(c => c.LoyaltyUserDetailId);
EF should create all foreign key you need and just don't care about WithMany !

There are several things wrong with your code.
A 1:1 relationship is either: PK<-PK, where one PK side is also an FK, or PK<-FK+UC, where the FK side is a non-PK and has a UC. Your code shows you have FK<-FK, as you define both sides to have an FK but that's wrong. I recon PIIUser is the PK side and LoyaltyUserDetail is the FK side. This means PIIUser doesn't have an FK field, but LoyaltyUserDetail does.
If the 1:1 relationship is optional, the FK side has to have at least 1 nullable field.
p.s.w.g. above did answer your question but made a mistake that s/he also defined an FK in PIIUser, which is of course wrong as I described above. So define the nullable FK field in LoyaltyUserDetail, define the attribute in LoyaltyUserDetail to mark it the FK field, but don't specify an FK field in PIIUser.
You get the exception you describe above below p.s.w.g.'s post, because no side is the PK side (principle end).
EF isn't very good at 1:1's as it's not able to handle unique constraints. I'm no expert on Code first, so I don't know whether it is able to create a UC or not.
(edit) btw: A 1:1 B (FK) means there's just 1 FK constraint created, on B's target pointing to A's PK, not 2.

public class User
{
public int Id { get; set; }
public int? LoyaltyUserId { get; set; }
public virtual LoyaltyUser LoyaltyUser { get; set; }
}
public class LoyaltyUser
{
public int Id { get; set; }
public virtual User MainUser { get; set; }
}
modelBuilder.Entity<User>()
.HasOptional(x => x.LoyaltyUser)
.WithOptionalDependent(c => c.MainUser)
.WillCascadeOnDelete(false);
this will solve the problem on REFERENCE and FOREIGN KEYS
when UPDATING or DELETING a record

Try adding the ForeignKey attribute to the LoyaltyUserDetail property:
public class PIIUser
{
...
public int? LoyaltyUserDetailId { get; set; }
[ForeignKey("LoyaltyUserDetailId")]
public LoyaltyUserDetail LoyaltyUserDetail { get; set; }
...
}
And the PIIUser property:
public class LoyaltyUserDetail
{
...
public int PIIUserId { get; set; }
[ForeignKey("PIIUserId")]
public PIIUser PIIUser { get; set; }
...
}

This is of no use to the original poster, but for anyone still on EF6 who needs the foreign key to be different from the primary key, here's how to do it:
public class PIIUser
{
public int Id { get; set; }
//public int? LoyaltyUserDetailId { get; set; }
public LoyaltyUserDetail LoyaltyUserDetail { get; set; }
}
public class LoyaltyUserDetail
{
public int Id { get; set; }
public double? AvailablePoints { get; set; }
public int PIIUserId { get; set; }
public PIIUser PIIUser { get; set; }
}
modelBuilder.Entity<PIIUser>()
.HasRequired(t => t.LoyaltyUserDetail)
.WithOptional(t => t.PIIUser)
.Map(m => m.MapKey("LoyaltyUserDetailId"));
Note that you can't use the LoyaltyUserDetailId field because, as far as I can tell, it can only be specified using the fluent API. (I've tried three ways of doing it using the ForeignKey attribute and none of them worked).

The one thing that is confusing with above solutions is that the Primary Key is defined as "Id" in both tables and if you have primary key based on the table name it wouldn't work, I have modified the classes to illustrate the same, i.e. the optional table shouldn't define it's own primary key instead should use the same key name from main table.
public class PIIUser
{
// For illustration purpose I have named the PK as PIIUserId instead of Id
// public int Id { get; set; }
public int PIIUserId { get; set; }
public int? LoyaltyUserDetailId { get; set; }
public LoyaltyUserDetail LoyaltyUserDetail { get; set; }
}
public class LoyaltyUserDetail
{
// Note: You cannot define a new Primary key separately as it would create one to many relationship
// public int LoyaltyUserDetailId { get; set; }
// Instead you would reuse the PIIUserId from the primary table, and you can mark this as Primary Key as well as foreign key to PIIUser table
public int PIIUserId { get; set; }
public double? AvailablePoints { get; set; }
public int PIIUserId { get; set; }
public PIIUser PIIUser { get; set; }
}
And then followed by
modelBuilder.Entity<PIIUser>()
.HasOptional(pi => pi.LoyaltyUserDetail)
.WithRequired(lu => lu.PIIUser);
Would do the trick, the accepted solution fails to clearly explain this, and it threw me off for few hours to find the cause

Related

Cross including the same table relations in EF Code Throws an error Multiplicity constraint violated

I have cross relations with the same table, in 3rd object.
When I try to insert new object, got an error :
Multiplicity constraint violated. The role
'OrgOwners_Organisation_Target' of the relationship
'GBankDataSource.OrgOwners_Organisation' has multiplicity 1 or 0..1.
I've tried to annotate [ForeignKey("...")] in any of the classes, but nothing happend. EF allways choose one field (OrgRefID in this sample) and use it or both relations, while OrgID are not used.
public class OrganisationInfo
{
[Key]
public int OrgID { get; set; }
...
public virtual List<OrgOwners> OrgOwners { get; set; } // object that throws error
}
public class OrgOwners
{
[Key]
public int OrgOwnerID { get; set; }
public int OrgID { get; set; } //Suppose to be a ForeignKey for (OrganisationInfo OrgOwners List)
public int? OrgRefID { get; set; }
...
[ForeignKey("OrgRefID")]
public virtual OrganisationInfo Organisation { get; set; } //(Suppose to use OrgRefID as ForeignKey)
}
When I add a record to OrgOwners without Organisation ( Organisation =null) - it is OK. But when I do
var first = new OrganisationInfo(); //First organisation DB.OrganisationInfoes.Add(first);
var nextOrg = new OrganisationInfo(); //second organisation
first.OrgOwners = new list();
var Owner = new OrgOwners(); Owner.Organsiation = nextOrg;
first.OrgOwners.Add(Owner); // Add Owner with the second organisation to the First one.
I got an error.
Multiplicity constraint violated.
OrgOwner.Organisation - is NOT the same OrganisationInfo as in root of OrgOwners list. It must be different OrganisationInfo items, related to OrgRefID ForeignKey.
It's because EF by default automatically "pairs" the navigation properties where possible to form a relationship. In your case, it pairs OrganizationInfo.OrgOwners collection navigation property with OrgOwners.Organization reference navigation property, hence takes and uses the associated with it OrgRefID FK.
One way to resolve the issue is to add a second reference navigation property to OrgOwners and associate it with the OrgID property via ForeignKey attribute and OrganizationInfo.OrgOwners collection navigation property via InverseProperty attribute:
public int OrgID { get; set; } //Suppose to be a ForeignKey for (OrganisationInfo OrgOwners List)
[ForeignKey("OrgID")]
[InverseProperty("OrgOwners")]
public virtual OrganisationInfo OwnerOrganization { get; set; }
To do that without changing the entity model, you should configure the relationship via fluent API:
modelBuilder.Entity<OrganisationInfo>()
.HasMany(e => e.OrgOwners)
.WithRequired() // no inverse navigation property
.HasForeignKey(e => e.OrgID); // <--
Full worked example:
public class OrganisationInfo
{
[Key]
public int OrgID { get; set; }
public virtual List<OrgOwners> OrgOwners { get; set; }
}
public class OrgOwners
{
[Key]
public int OrgOwnerID { get; set; }
public int OrgID { get; set; }
public int? OrgRefID { get; set; }
[ForeignKey("OrgRefID")]
public virtual OrganisationInfo Organisation { get; set; }
}
modelBuilder.Entity<OrganisationInfo>()
.HasMany(e => e.OrgOwners)
.WithRequired()
.HasForeignKey(e => e.OrgID);

One-To-One relationship with FK distinct from PK

I have 2 tables in database: ReceivedGoods and ReceivedGoodsProperties
ReceivedGoods contains ReceivingId as PK and must have its extending data in ReceivedGoodsProperties which contains ReceivingId as FK referencing to the ReceivedGoods's ReceivingId. Current ReceivedGoodsProperties, however, has its own PK Id and is therefore distinct from FK. So I have following:
public class ReceivedGoods
{
...
public int ReceivingId { get; set; }
...
public virtual ReceivedGoodsProperties properties { get; set; }
}
public class ReceivedGoodsProperties
{
...
public int Id { get; set; } // This is PK
public int ReceivingId { get; set; } // This is FK
...
public virtual ReceivedGoods goods { get; set; }
}
I would like to get ReceivedGoods object and have properties automatically loaded as well but I am not able to figure out, how to set up this within EF.
I've tried something like this (from the ReceivedGoodsProperties side mapping):
this.HasRequired(p => p.goods)
.WithRequiredDependent(d => d.properties)
.Map(m => m.MapKey("ReceivingId"));
but I am ending up with following error:
ReceivingId: Name: Each property name in a type must be unique. Property
name 'ReceivingId' is already defined.
When commenting out ReceivingId in ReceivedGoodsProperties, upper exception is not thrown, ReceivedGoods is loaded correctly except the properties property.
Can somebody explain me, how to do one-to-one mapping in situation like this?
Could you try:
public class ReceivedGoods
{
...
public int ReceivingId { get; set; }
...
public virtual ReceivedGoodsProperties properties { get; set; }
}
public class ReceivedGoodsProperties
{
...
public int Id { get; set; } // This is PK
[ForeignKey( "goods " )]
public int ReceivingId { get; set; } // This is FK
...
[Required]
public virtual ReceivedGoods goods { get; set; }
}
BTW, in C# the standard guidelines is to PascalCase members, so Goods and Properties
Try defining the relationship this way:
this.HasRequired(p => p.goods)
.WithRequiredDependent(p => p.properties)
.HasForeignKey(p => p.ReceivingId);
If you follow the standard EF naming conventions, it can usually figure out these relationships on its own. You only really run in to trouble when your navigation property names don't correspond to the class name, or if you have multiple FKs to the same destination in the source table.
If you want the navigation properties to get filled out "automatically", use the Include extension method on the query, as in:context.Goods.Include(g=>g.properties). You don't have to declare them as virtual unless you want to make use of lazy loading.
You may need to come at this from the other entity:
this.HasRequired(p => p.properties)
.WithRequiredPrincipal(p => p.goods)
.HasForeignKey(p => p.ReceivingId);

.Net Entity Framework Cyclic Cascade Paths

I'm having some issues creating foreign key relationships between my tables using the C# Entity Framework. I have these tables:
CREATE TABLE [dbo].[Course] (
[Id] INT IDENTITY (1, 1) NOT NULL,,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED ([ID] ASC)
);
CREATE TABLE [dbo].[PreqEdge] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[ParentID] INT NOT NULL,
[ChildID] INT NOT NULL,
CONSTRAINT [PK_PreqEdge] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Dependant] FOREIGN KEY ([ParentID]) REFERENCES [dbo].[Course] ([Id]),
CONSTRAINT [FK_Depends] FOREIGN KEY ([ChildID]) REFERENCES [dbo].[Course] ([Id])
);
The corresponding models look like so:
public partial class Course
{
public int Id { get; set; }
public virtual ICollection<PreqEdge> Parents { get; set; }
public virtual ICollection<PreqEdge> Children { get; set; }
public Course()
{
Parents = new HashSet<PreqEdge>();
Children = new HashSet<PreqEdge>();
}
}
public partial class PreqEdge
{
public int Id { get; set; }
public int ParentID { get; set; }
public int ChildID { get; set; }
public virtual Course Parent { get; set; }
public virtual Course Child { get; set; }
}
Whenever I use my database context to access them I get this error:
Introducing FOREIGN KEY constraint 'FK_dbo.PreqEdges_dbo.Courses_ChildID' on table 'PreqEdges' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
The purpose of these tables is to connect two Courses together like the edge of a graph in order to create a chain of prerequisites for that course that can be traversed either forwards or backwards based on whether you filter by ChildID or ParentID.
I understand that Entity Framework by default uses cascade deletes on references and that I might be able to solve this by overriding the OnModelCreating method in my DbContext, but I'm not sure how to specify using a DbModelBuilder this kind of relationship where it could be foreign keyed with a table by either one of two keys in that table.
Is this possible to do in the Entity Framework without manually writing SQL calls?
EDIT: Changed DependantID and DependsID to ParentID and ChildID for clarity
You will have to check for circular references with your model setup like that. In this model every course can connect with every course. It might be easier to reduce the flexibility of your model somehow, if possible.
Here is Object model as an example of various circular reference situations you can get:
Inspiration how to reduce the chance of circular reference:
You can divide Courses into groups by CourseType and e.g. SpecializedCourse cannot be a Parent of any Course but can be a Child of a GeneralCourse.
I found a link with the correct solution. For this example you would do something like this:
public class Course
{
public int Id { get; set; }
public string CouresNumber { get; set; }
public virtual ICollection<PreqEdge> Parents { get; set; }
public virtual ICollection<PreqEdge> Children { get; set; }
}
public class PreqEdge
{
public int Id { get; set; }
public int ParentId { get; set; }
public int ChildId { get; set; }
public virtual Course Parent { get; set; }
public virtual Course Child { get; set; }
}
public class CourseContext : DbContext
{
public DbSet<Course> Courses { get; set; }
public DbSet<PreqEdge> PreqEdges { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PreqEdge>()
.HasRequired(e => e.Parent)
.WithMany(c => c.Parents)
.HasForeignKey(e => e.ParentId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<PreqEdge>()
.HasRequired(e => e.Child)
.WithMany(c => c.Children)
.HasForeignKey(e => e.ChildId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
}
Another mistake I made was to try to mix code first and database first.
Try two ways.
1) set lazy loading off in constructor of DbContext class
this.Configuration.LazyLoadingEnabled = false;
It will not allow to load referencing objects
or
2) use [notmapped] on PreqEdge referencing properties as
[notmapped]
public virtual Course Parent { get; set; }
[notmapped]
public virtual Course Child { get; set; }
This is just to break the cycle.

How to make proper code-first relations

I'm fairly new to Entity Framework and feel more in control using the Code-First pattern rather than DB-First.
I was wondering what is more preferred when it comes to programmatically setting up ForeignKey relations between the entities.
Is it better to declare a FK_ property in the class which relates to the another class or is it better to declare an IEnumerable<> property in the class that gets related to?
public class IRelateToAnotherClass
{
...
public int FK_IGetRelatedToByAnotherClass_ID { get; set; }
}
or
public class IGetRelatedToByAnotherClass
{
...
public IEnumerable<IRelateToAnotherClass> RelatedTo { get; set; }
}
It all depends on what type of relationships you want between your entities (one-to-one, one-to-many, many-to-many); but, yes, you should declare foreign key properties. Check out this site for some examples.
Here's a one-to-many for your two classes:
public class IRelateToAnotherClass
{
public int Id { get; set; } // primary key
public virtual ICollection<IGetRelatedToByAnotherClass> IGetRelatedToByAnotherClasses { get; set; }
}
public class IGetRelatedToByAnotherClass
{
public int Id { get; set; } // primary key
public int IRelateToAnotherClassId { get; set; } // foreign key
public virtual IRelateToAnotherClass IRelateToAnotherClass { get; set; }
}
and with some Fluent API mapping:
modelBuilder.Entity<IGetRelatedToByAnotherClass>.HasRequired<IRelateToAnotherClass>(p => p.IRelateToAnotherClass).WithMany(p => p.IGetRelatedToByAnotherClasses).HasForeignKey(p => p.Id);
If I understand what you're asking correctly, you'd want both. You want an int FK property and an object property to use as the navigation property.
The end result would look something like this:
public class Employee
{
[Key]
public int EmployeeID { get; set; }
[ForeignKey("Store")]
public int StoreNumber { get; set; }
// Navigation Properties
public virtual Store Store { get; set; }
}
public class Store
{
[Key]
public int StoreNumber { get; set; }
// Navigation Properties
public virtual List<Employee> Employees { get; set; }
}
If you haven't already, take a look at navigation properties and lazy-loading. Note that EF is clever enough to figure out that an int StoreID property corresponds to an object Store property, but if they are named differently (such as without the ID suffix), you must use the [ForeignKey] annotation.

How do I create a table that has a composite key each member of which is a foreign key member to other tables

I am trying to do code first with annotations (for the first time) on an MVC project.
I have created the following POCOs.
[Table("Customers")]
public partial class Customer
{
public int Id { get; set; }
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
[DisplayName("Last Name")]
[Required]
public string LastName { get; set; }
//other properties...
}
[Table("Vehicles")]
public partial class Vehicle
{
[Required]
public int Id { get; set; }
[Required]
public int CustomerId { get; set; }
[Required]
public string Make { get; set; }
[Required]
public string Model { get; set; }
[Required]
public string Year { get; set; }
//other fields
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
}
[Table("CustomerAppointments")]
public partial class CustomerAppointment
{
[Key,Column(Order=0)]
public int CustomerId { get; set; }
[Key,Column(Order=1)]
public int VehicleId { get; set; }
public DateTime? AppointmentDate { get; set; }
public DateTime? AppointmentTime { get; set; }
public string AvailableDays { get; set; }
//other fields
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
[ForeignKey("VehicleId")]
public virtual Vehicle Vehicle { get; set; }
}
I think my intent here is fairly obvious. I have customers. Those customers have vehicles. I want to create a table CustomerAppointments where a customer and one of the customers vehicles is scheduled for a service.
For the record, this is not the whole model and has been simplified for the purposes of the question.
I am using MvcScaffolding to build out the EF items and the views.
Everything compiles but when I try to navigate to the Customers page (actually a class not mentioned that references customers) I am getting the following error...
Introducing FOREIGN KEY constraint 'FK_dbo.CustomerAppointments_dbo.Vehicles_VehicleId' on table 'CustomerAppointments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I have tried different annotations and even tried to use the fluent API with something like this...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CustomerAppointment>()
.HasRequired(ca => ca.Customer)
.WithRequiredPrincipal()
.WillCascadeOnDelete(false);
modelBuilder.Entity<CustomerAppointment>()
.HasRequired(ca => ca.Vehicle)
.WithRequiredPrincipal()
.WillCascadeOnDelete(false);
}
But I cannot get it to work. I have read every sample I can find on google and SO but to no avail.
PS...if this can work with Annotations only that would be my preference.
Your model has two cascading delete paths from Customer to CustomerAppointment when a Customer is deleted:
Customer -> Vehicle -> CustomerAppointment
Customer -> CustomerAppointment
That's not allowed in SQL Server and causes the exception. You need to disable cascading delete for at least one of those three subpaths which is only possible with Fluent API. For example the Customer -> Vehicle path:
modelBuilder.Entity<Vehicle>()
.HasRequired(v => v.Customer)
.WithMany()
.HasForeignKey(v => v.CustomerId)
.WillCascadeOnDelete(false);
You could also make CustomerId nullable to have an optional relationship in which case EF will disable cascading delete by default. But changing a required to an optional relationship expresses a change in business rules which I wouldn't do just to avoid Fluent API.
BTW: Is it really correct that CustomerAppointment should have a composite primary key? It would mean that a given customer with a given vehicle could only have one service appointment. Couldn't there be many appointments for the same customer/vehicle combination at different appointment dates? If yes, you should rather have a separate key for CustomerAppointment and CustomerId and VehicleId would be just foreign keys without being part of the primary key.
It seems like you are better off using the database-first approach and then generating the model using ado enity data model.
By convention, cascade deletes are handled by the introduction of the actual foreign key into your model. If you use a non-nullable foreign key, it will require delete. Use a nullable foreign key to turn it off.
Change your class to the following by making the foreign keys nullable:
[Table("CustomerAppointments")]
public partial class CustomerAppointment
{
[Key,Column(Order=0)]
public int? CustomerId { get; set; }
[Key,Column(Order=1)]
public int? VehicleId { get; set; }
public DateTime? AppointmentDate { get; set; }
public DateTime? AppointmentTime { get; set; }
public string AvailableDays { get; set; }
//other fields
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
[ForeignKey("VehicleId")]
public virtual Vehicle Vehicle { get; set; }
}
Remember to also remove the fluent mapping.
From http://msdn.microsoft.com/en-US/data/jj679962
If a foreign key on the dependent entity is not nullable, then Code
First sets cascade delete on the relationship. If a foreign key on the
dependent entity is nullable, Code First does not set cascade delete
on the relationship, and when the principal is deleted the foreign key
will be set to null.

Categories