How can I configure relationships between three tables to get all related data?
I have the following models (and the same tables in database):
public class Client
{
public Guid ClientId { get; set; }
public string FirstName { get; set; }
public virtual ClientCard ClientCard { get; set; }
}
public class Card
{
public Guid CardId { get; set; }
public string Number { get; set; }
public virtual ClientCard ClientCard { get; set; }
}
public class ClientCard
{
public Guid ClientCardId { get; set; }
public Guid CardId { get; set; }
public Guid ClientId { get; set; }
public virtual Client Client { get; set; }
public virtual Card Card { get; set; }
}
And the following OnModelCreating method:
protected override void OnModelCreating(DbModelBuilder builder)
{
builder.Conventions.Remove<PluralizingTableNameConvention>();
...
builder.Entity<ClientCard>()
.HasKey(x => x.ClientCardId);
builder.Entity<ClientCard>()
.HasRequired(x => x.Client)
.WithRequiredPrincipal(x => x.ClientCard);
builder.Entity<ClientCard>()
.HasRequired(x => x.Card)
.WithRequiredPrincipal(x => x.ClientCard);
base.OnModelCreating(builder);
}
But the results return without related data. Why?
For your code please try something like:
public class Client
{
public Guid ClientId { get; set; }
public string FirstName { get; set; }
public virtual ICollection<ClientCard> ClientCard { get; set; }
}
public class Card
{
public Guid CardId { get; set; }
public string Number { get; set; }
public virtual ICollection<ClientCard> ClientCard { get; set; }
}
public class ClientCard
{
public Guid ClientCardId { get; set; }
public Guid CardId { get; set; }
public Guid ClientId { get; set; }
public virtual Client Client { get; set; }
public virtual Card Card { get; set; }
}
And mapping:
builder.Entity<Client>()
.HasKey(t => t.ClinetID);
....
builder.Entity<Client>()
.HasMany(a => a.ClientCard)
.WithRequired(p => p.Client)
.HasForeignKey(p => p.ClientID);
For Card
....
builder.Entity<Card>()
.HasMany(a => a.ClientCard)
.WithRequired(p => p.Card)
.HasForeignKey(p => p.CardID);
But I think the best way is to create a separate map-file for each entities
Now I am using the following models:
public class Client
{
public Guid ClientId { get; set; }
public string FirstName { get; set; }
public Guid? CardId { get; set; }
public virtual Card Card { get; set; }
}
public class Card
{
public Guid CardId { get; set; }
public string Number { get; set; }
//public virtual Client Client { get; set; }
}
and the following OnModelCreating method:
protected override void OnModelCreating(DbModelBuilder builder)
{
builder.Conventions.Remove<PluralizingTableNameConvention>();
...
builder.Entity<Client>()
.HasOptional(x => x.Card)
//.WithOptionalPrincipal(x=> x.Client)
//or
//.WithOptionalDependent(x=> x.Client)
;
base.OnModelCreating(builder);
}
All clients return with related data(if exists). But if I want to get ralated data with Card object and uncomment public virtual Client Client { get; set; }
public virtual Client Client { get; set; }
public virtual Client Client { get; set; }
and WithOptionalPrincipal/WithOptionalDependent I always get on of these SqlException: "invalid column name 'Client_ClientId'" (if WithOptionalPrincipal is used) OR "invalid column name 'Card_CardId'" (if WithOptionalDependent is used)
I finally found a solution for my case.
First, I have removed CardId from Client class. Second, I have changed my OnModelCreating method:
protected override void OnModelCreating(DbModelBuilder builder)
{
builder.Conventions.Remove<PluralizingTableNameConvention>();
...
builder.Entity<Client>()
.HasOptional(x => x.Card)
.WithOptionalDependent(x => x.Client)
.Map(x => x.MapKey("CardId"))
.WillCascadeOnDelete(false);
builder.Entity<Card>()
.HasOptional(x => x.Client)
.WithOptionalPrincipal(x => x.Card)
.WillCascadeOnDelete(false);
base.OnModelCreating(builder);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.