Data Access has been discontinued. Please refer to this page for more information.

How to: Manage One-to-One Associations

Suppose you have the following model that includes two entities Orders and OrderDetails connected through a one-to-one association. The OrderDetails entity has exactly one instance of Orders.

In the model, you can use a OrderDetails.Orders property to access the Orders instance that is associated with an instance of the OrderDetails entity. The Orders entity may have only one instance of OrderDetails. You can use a Orders.OrderDetails property to access the OrderDetails instances that is associated with the instance of the Orders entity. Below is an example of the mapping for the two properties:

orderConfiguration.HasAssociation(x => x.OrderDetails).
    HasFieldName("_orderDetails").WithOpposite(x => x.Order).
    ToColumn("OrderID").HasConstraint((y, x) =>  x.OrderID == y.OrderID ).
    WithataAccessKind(DataAccessKind.ReadWrite);
orderDetailsConfiguration.HasAssociation(x => x.Order).
    HasFieldName("_order").WithOpposite(x => x.OrderDetails).
    ToColumn("OrderID").HasConstraint((x, y) =>  x.OrderID == y.OrderID ).
    IsRequired().WithDataAccessKind(DataAccessKind.ReadWrite);
orderConfiguration.HasAssociation(x => x.OrderDetails).
    HasFieldName("_orderDetails").WithOpposite(x => x.Order).
    ToColumn("OrderID").HasConstraint((y, x) =>  x.OrderID == y.OrderID ).
    WithataAccessKind(DataAccessKind.ReadWrite)
orderDetailsConfiguration.HasAssociation(x => x.Order).
    HasFieldName("_order").WithOpposite(x => x.OrderDetails).
    ToColumn("OrderID").HasConstraint((x, y) =>  x.OrderID == y.OrderID ).
    IsRequired().WithDataAccessKind(DataAccessKind.ReadWrite)

In this scenario, by default Telerik Data Access manages the association (you do not need to explicitly set IsManaged). You can access and modify the related objects without any concerns about introducing changes in the database that are not compatible with the relational model.

IsManaged notifies Telerik Data Access whether to populate the foreign key column of the child table in the database with the appropriate value when a new child object is added to the collection navigation property of a parent object. Since OrderDetails.Orders and Orders.OrderDetails are not collections, IsManaged is not required.

Below you can find how to insert and delete objects from domain entities related through a one-to-one association:

In case you need to insert a new order with the appropriate details, you can do it like this:

using (FluentModel dbContext = new FluentModel())
{
    Orders newOrder = new Orders()
    {
        Id = 1,
        DateCreated = DateTime.Now
    };
    OrderDetails newOrderDetails = new OrderDetails()
    {
        Customer = "Customer Name",
        Employee = "Employee Name",
        Product = "Product Name"
    };
    dbContext.Add(newOrder);
    newOrder.OrderDetails = newOrderDetails;
    dbContext.SaveChanges();
}
Using dbContext As New FluentModel()
    Dim newOrder As New Orders() With 
    {
        .Id = 1, 
        .DateCreated = Date.Now
    }
    Dim newOrderDetails As New OrderDetails() With 
    {
        .Customer = "Customer Name", 
        .Employee = "Employee Name", 
        .Product = "Product Name"
    }
    dbContext.Add(newOrder)
    newOrder.OrderDetails = newOrderDetails
    dbContext.SaveChanges()
End Using

Note that in this case only the newOrder is added to the context and newOrderDetails is assigned to the navigation property. After the call to the SaveChanges() method both objects are saved in the database keeping the relationship between them. This is called persistence by reachability, which means that if you build a graph of related objects, adding the top most one to the context will cause the context to track the rest too.

For general information about inserting objects you can check the How to: Insert Objects article.

In case you need to delete an order from Orders (the parent table), you need to make sure that the corresponding object in OrderDetails is removed first. For example:

using (FluentModel dbContext = new FluentModel())
{
    Orders someOrder = dbContext.Orders.FirstOrDefault();
    dbContext.Delete(someOrder.OrderDetails);
    dbContext.Delete(someOrder);
    dbContext.SaveChanges();
}
Using dbContext As New FluentModel()
    Dim someOrder As Orders = dbContext.Orders.FirstOrDefault()
    dbContext.Delete(someOrder.OrderDetails)
    dbContext.Delete(someOrder)
    dbContext.SaveChanges()
End Using

If the order details are not removed prior to the removal of the order you will experience DataStoreException: The DELETE statement conflicted with the REFERENCE constraint.

In case you need to remove only the details about a given order, you can pass someOrder.OrderDetails to the Delete() method of the context and then call SaveChanges().

For general information about deleting objects you can check the How to: Delete Objects article.