Proper pattern to handle one-to-many with differen

2019-07-07 17:07发布

I have a C# project and I use Entity Framework as the ORM. I have a User, which is able to pay to many banks. Each bank is a separate entity and each one of them is described by different fields.

The problem is - one User can have no-or-many different Banks. I'm not really sure how to model this - the temporary solution was to add an additional UserBank entity, which is in 1:1 realtionship with User. The classes look (more or less) like that:

public class User
{
  public virtual UserBank Banks { get; set; }
  // (...)
}

and

public class UserBank
{
  public virtual User { get; set; }
  public virtual Bank1 { get; set; }
  public virtual Bank2 { get; set; }
  public virtual Bank3 { get; set; }
}

In that scenario, User may or may not have accounts in any of the Banks. If he doesn't have one, the value will be NULL.

It's not perfect - but at least User doesn't need to know anything about Bank types. The problem is that if I want to add a new Bank, I need to modify UserBank entity, which is violating the O in SOLID, which I try to always follow.

Additionally, I don't like the idea that UserBank has to store N empty (NULL) columns for N banks if User doesn't have any bank accounts. Is there a proper pattern to handle that situation?


EDIT

I am aware that it's a relatively easy problem in raw SQL. The problem here is how to do that with Entity Framework with code-first.

1条回答
啃猪蹄的小仙女
2楼-- · 2019-07-07 17:27

This looks like a classical m:n relationship. Each User can have different banks and each bank will have many users.

You need three tables:

  • User (UserID, Name, ...)
  • Bank (BankID, Name, ...)
  • UserBank(UserBankID, UserID FK-to-User, BankID FK-to-Bank, FurtherDetails ...)

If you want to ensure, that a user cannot have multiple connections with the same bank, you might place a unique key on the combination of UserID/BankID or let this be the PK of you mapping table. But I don't think this was correct actually...

The entity tables (User/Bank) hold a description of their object, but nothing more. The mapping table gets all the needed data which describes the connection between these two (date of creation, active, account (which should be a FK to another entity table) and so on...)

UPDATE example to illustrate a m:n-relationship

User

  1 John
  2 Jane
  3 Tim

Bank

 1 Bank of England
 2 Deutsche Bank
 3 Crash & Desaster

UserBank

 1 1 1 --> User 1 is connected with Bank 1 --> John uses BoE  
 2 1 2 --> John uses Deutsche Bank too  
 3 2 1 --> And Jane is at Deutsche Bank  
 4 3 3 --> while Tim is at C&D  

UPDATE 2

No experience with EF code first, but this would be the line in C#:

public class User
{
  public int UserID{get;set}
  public string Name...
  public List<UserBank> MyBanks{ ... fetch by this.UserID ... }
}
public class Bank
{
  public int BankID{get;set}
  public string Name{get;set;}
  public List<UserBank> MyUsers{... fetch by this.BankID ... }
}

public class UserBank
{
  public int UserBankID{get;set}
  public User{get;set;}
  public Bank{get;set;} 
}
查看更多
登录 后发表回答