One-to-One Associations
This topic illustrates how to configure one-to-one associations. The workflow for defining one-to-one associations is the same as defining any normal one-to-many association. The only detail here is that, when the members(columns) selected for the source and target entity are Primary Keys, the created association is automatically created as one-to-one instead of one-to-many.
The following example demonstrates how to create an one-to-one association between the Customer and the CustomerDetail classes. If Customer and CustomerDetail are reference properties, the association created is automatically derived to be one-to-one. The only thing that should be paid attention to, is the IsRequired method call. IsRequired should be defined on the source end of the association so Telerik Data Access "knows" which side should be the source and which the target of the association. This is important because, when there is a constraint between the primary keys in the database, the record in the "target" table should be inserted first and the record in the source table should be inserted after that. Setting IsRequired on the correct side tells Telerik Data Access which side of the one-to-one association should be inserted first in the database. Sample FluentMetadataSource implementation could be found at the end of the topic.
customerDetailConfiguration
.HasAssociation(x => x.Customer)
.WithOpposite(o => o.CustomerDetail)
.HasConstraint((x, o) => x.CustDetailId == o.CustomerId)
.IsRequired();
customerDetailConfiguration.
HasAssociation(x => x.Customer).
WithOpposite(o => o.CustomerDetail).
HasConstraint((x, o) => x.CustDetailId == o.CustomerId).
IsRequired()
Customer
public class Customer
{
public int CustomerId {get;set;}
public string Name {get;set;}
public string Type {get;set;}
public CustomerDetail CustomerDetail {get;set;}
}
Public Class Customer
Private _customerId As Integer
Public Property CustomerId() As Integer
Get
Return Me._customerId
End Get
Set(ByVal value As Integer)
Me._customerId = value
End Set
End Property
Private _name As String
Public Property Name() As String
Get
Return Me._name
End Get
Set(ByVal value As String)
Me._name = value
End Set
End Property
Private _type As String
Public Property Type() As String
Get
Return Me._type
End Get
Set(ByVal value As String)
Me._type = value
End Set
End Property
Private _customerDetail As CustomerDetail
Public Property CustomerDetail() As CustomerDetail
Get
Return Me._customerDetail
End Get
Set(ByVal value As CustomerDetail)
Me._customerDetail = value
End Set
End Property
End Class
CustomerDetail
public class CustomerDetail
{
public int CustDetailId {get;set;}
public string Address {get;set;}
public string Phone {get;set;}
public Customer Customer {get;set;}
}
Public Class CustomerDetail
Private _custDetailId As Integer
Public Property CustDetailId() As Integer
Get
Return Me._custDetailId
End Get
Set(ByVal value As Integer)
Me._custDetailId = value
End Set
End Property
Private _address As String
Public Property Address() As String
Get
Return Me._address
End Get
Set(ByVal value As String)
Me._address = value
End Set
End Property
Private _phone As String
Public Property Phone() As String
Get
Return Me._phone
End Get
Set(ByVal value As String)
Me._phone = value
End Set
End Property
Private _customer As Customer
Public Property Customer() As Customer
Get
Return Me._customer
End Get
Set(ByVal value As Customer)
Me._customer = value
End Set
End Property
End Class
Sample FluentMetadataSource Implementation - One-To-One Association
public class FluentModelMetadataSource : FluentMetadataSource
{
protected override IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> configurations = new List<MappingConfiguration>();
MappingConfiguration<Customer> customerConfiguration = new MappingConfiguration<Customer>();
customerConfiguration.MapType( c => new
{
Id = c.CustomerId,
Name = c.Name,
Type = c.Type
} ).ToTable( "Customers" );
customerConfiguration.HasProperty( p => p.CustomerId ).IsIdentity( KeyGenerator.Autoinc );
MappingConfiguration<CustomerDetail> customerDetailConfiguration = new MappingConfiguration<CustomerDetail>();
customerDetailConfiguration.MapType( c => new
{
Id = c.CustDetailId,
Name = c.Address,
Type = c.Phone
} ).ToTable( "CustomerDetails" );
customerDetailConfiguration.HasProperty( p => p.CustDetailId ).IsIdentity();
customerDetailConfiguration
.HasAssociation(x => x.Customer)
.WithOpposite(o => o.CustomerDetail)
.HasConstraint((x, o) => x.CustDetailId == o.CustomerId)
.IsRequired();
configurations.Add( customerConfiguration );
configurations.Add( customerDetailConfiguration );
return configurations;
}
}
Public Class FluentModelMetadataSource
Inherits FluentMetadataSource
Protected Overrides Function PrepareMapping() As IList(Of MappingConfiguration)
Dim configurations As New List(Of MappingConfiguration)()
Dim customerConfiguration As New MappingConfiguration(Of Customer)()
customerConfiguration.MapType(Function(c) New With {
Key .Id = c.CustomerId,
Key .Name = c.Name,
Key .Type = c.Type}).ToTable("Customers")
customerConfiguration.HasProperty(Function(p) p.CustomerId).IsIdentity(KeyGenerator.Autoinc)
customerConfiguration.FieldNamingRules.AddPrefix = "_"
Dim customerDetailConfiguration As New MappingConfiguration(Of CustomerDetail)()
customerDetailConfiguration.MapType(Function(c) New With {
Key .Id = c.CustDetailId,
Key .Name = c.Address,
Key .Type = c.Phone}).ToTable("CustomerDetails")
customerDetailConfiguration.HasProperty(Function(p) p.CustDetailId).IsIdentity()
customerDetailConfiguration.FieldNamingRules.AddPrefix = "_"
customerDetailConfiguration.HasAssociation(Function(x) x.Customer).
WithOpposite(Function(o) o.CustomerDetail).
HasConstraint(Function(x, o) x.CustDetailId = o.CustomerId).IsRequired()
configurations.Add(customerConfiguration)
configurations.Add(customerDetailConfiguration)
Return configurations
End Function
End Class