.net EF代码优先数据库架构:用两个表表示用户实体,应使用其中一个表

ubof19bj  于 2023-03-31  发布在  .NET
关注(0)|答案(1)|浏览(95)

我以这种方式对数据库进行建模,虽然它工作得很好,但我无法将其集成到现有系统中,因为该系统中的User由两个表表示:员工和客户。系统用户有内部(员工)和外部(客户)。如果你看我下面做的架构,你会看到UserNotificationSettings中的UserId是PK和FK。这必须改变。
问题是我应该在下面的数据库设计中做什么修改,以便UserId同时成为EmployeeId和CustomerId。顺便说一下,EmployeeId或CustomerId应该使用,而不是两者都使用。

public class EventType
{
    public Guid Id { get; set; }
    public string Name { get; set; } = default!;

    public ICollection<UserNotificationSettings> UserNotificationSettings { get; set; } = default!;
    public ICollection<GlobalNotificationSettings> GlobalNotificationSettings { get; set; } = default!;
    public ICollection<Notification> Notifications { get; set; } = default!;
}

public class GlobalNotificationSettings
{
    public bool IsInternalNotificationsEnabled { get; set; }
    public bool IsEmailNotificationsEnabled { get; set; }
    public bool IsSmsNotificationsEnabled { get; set; }
    
    public Guid EventTypeId { get; set; }
    public EventType EventType { get; set; } = default!;
}

public class Notification
{
    public Guid Id { get; set; }
    public bool Seen { get; set; }
    public DateTime CreatedAt { get; set; }
    
    public Guid UserId { get; set; }
    public User User { get; set; } = default!;
    
    public Guid EventTypeId { get; set; }
    public EventType EventType { get; set; } = default!;
}

public class Sound
{
    public Guid Id { get; set; }
    public string Name { get; set; } = default!;
    public string Url { get; set; } = default!;
    
    public ICollection<UserNotificationSettings> UserNotificationSettings { get; set; } = default!;
}

public class User
{
    public Guid Id { get; set; }
    public string Username { get; set; } = default!;
    public string Password { get; set; } = default!;
    public string Email { get; set; } = default!;
    public string Phone { get; set; } = default!;

    public ICollection<UserNotificationSettings> UserNotificationSettings { get; set; } = default!;
}

public class UserNotificationSettings
{
    public bool IsInternalNotificationsEnabled { get; set; }
    public bool IsEmailNotificationsEnabled { get; set; }
    public bool IsSmsNotificationsEnabled { get; set; }
    public DeliveryOption EmailDeliveryOption { get; set; }
    public DeliveryOption SmsDeliveryOption { get; set; }
    
    public Guid UserId { get; set; }
    public User User { get; set; } = default!;
    
    public Guid EventTypeId { get; set; }
    public EventType EventType { get; set; } = default!;

    public Guid? SoundId { get; set; }
    public Sound? Sound { get; set; }
}

public enum DeliveryOption
{
    Immediate,
    DailySummary
}

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }

    public DbSet<User> Users => Set<User>();
    public DbSet<UserNotificationSettings> UserNotificationSettings => Set<UserNotificationSettings>();
    public DbSet<Sound> Sounds => Set<Sound>();
    public DbSet<EventType> EventTypes => Set<EventType>();
    public DbSet<Notification> Notifications => Set<Notification>();

    public DbSet<GlobalNotificationSettings> GlobalNotificationSettings => Set<GlobalNotificationSettings>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserNotificationSettings>(entity =>
        {
            entity.HasKey(uns => new { uns.UserId, uns.EventTypeId });
            
            entity.HasOne(uns => uns.User)
                .WithMany(u => u.UserNotificationSettings)
                .HasForeignKey(uns => uns.UserId)
                .OnDelete(DeleteBehavior.Cascade);
            
            entity.HasOne(uns => uns.EventType)
                .WithMany(et => et.UserNotificationSettings)
                .HasForeignKey(uns => uns.EventTypeId)
                .OnDelete(DeleteBehavior.Cascade);
            
            entity.HasOne(uns => uns.Sound)
                .WithMany(s => s.UserNotificationSettings)
                .HasForeignKey(uns => uns.SoundId)
                .OnDelete(DeleteBehavior.SetNull);
        });
        
        modelBuilder.Entity<GlobalNotificationSettings>(entity =>
        {
            entity.HasKey(gns => gns.EventTypeId);

            entity.HasOne(gns => gns.EventType)
                .WithMany(et => et.GlobalNotificationSettings)
                .HasForeignKey(gns => gns.EventTypeId)
                .OnDelete(DeleteBehavior.Cascade);
        });
        
        modelBuilder.Entity<Notification>(entity =>
        {
            entity.HasKey(n => n.EventTypeId);

            entity.HasOne(n => n.EventType)
                .WithMany(et => et.Notifications)
                .HasForeignKey(n => n.EventTypeId)
                .OnDelete(DeleteBehavior.Cascade);
            
            entity.HasOne(n => n.User)
                .WithMany(u => u.Notifications)
                .HasForeignKey(n => n.UserId)
                .OnDelete(DeleteBehavior.Cascade);
        });
    }
}
eivgtgni

eivgtgni1#

根据您的问题,您有一个客户表和一个雇员表。

Customer
--------
Customer number   PK
Other customer information

Employee
--------
Employee number   PK
Other employee information

现在,您需要创建多个具有以下结构的附加表。

Additional
----------
Number   PK
COE Flag   (Customer or employee)
Additional information

您编写SQL以这种方式连接此表和customer表。语法将根据您使用的关系数据库而有所不同。

SELECT Additional information, Customer information
FROM Additional, Customer
WHERE Additional informaton meets some criteria
AND Number = Customer Number
AND COE Flag = 'C'

您编写SQL以这种方式连接此表和employee表。语法将根据您使用的关系数据库而有所不同。

SELECT Additional information, Employee information
FROM Additional, Employee
WHERE Additional informaton meets some criteria
AND Number = Employee Number
AND COE Flag = 'E'

我不知道如何使概念更清晰。

相关问题