0

[我很惊讶我没有找到一个现有问题来回答这个概念性问题。也许我只是没有搜索正确的关键字。]

考虑一个具有一些自身属性的实体类型“Singer”。接下来,考虑一个实体类型“Quartet”,其中正好有四个 Singer,分配给四重奏中的角色“Tenor”、“Lead”、“Baritone”和“Bass”。

首先对该代码建模的最简单方法是向 Quartet 实体类中添加四个 Singer 导航属性,其中包含该四重奏中四个歌手角色的名称。这将导致一个 Quartet 表和一个具有四行的 Singers 表,其中外键引用该 quartet,并且我们有一对四的关系。不可怕,这很有效,但它会导致以后程序中的一些尴尬。

有许多操作需要对四个歌手进行迭代并为每个歌手完成,或者需要对其中一个歌手进行操作的条件查询,这取决于一些外部枚举的值,该值指示要对哪个歌手进行操作.

理想情况下,我希望拥有一个固定大小为 4 的 Singer 数组,而不是四个单独的 Singer 导航属性,其中数组的元素直接对应于枚举值,并且我可以遍历数组或根据枚举直接转到特定元素。

但这似乎在 EF 和 SQL Server 中不能很好地建模。

我怎样才能在这里完成我所需要的?

4

1 回答 1

2

考虑下一个代码示例:

public class Singer {
    public int Id { get; set; }
    public string Name { get; set; }
    public SingerType SingerType { get; set; }
    public virtual Quartet Quartet { get; set; }
}

public class Quartet {
    public int Id { get; set; }
    public virtual List<Singer> Singers { get; set; }
    public string Name { get; set; }

    public Singer GetByType(SingerType type) {
        return Singers.FirstOrDefault(e => e.SingerType == type);
    }

    public void AddSinger(Singer singer) {
        if (Singers.Any(e => e.SingerType == singer.SingerType)) {
            throw new Exception($"You cannot add additional-{singer.SingerType} to quartet->{this.Name}");
        }
        if (Singers.Count > 3) {
            throw new Exception($"You cannot add additional singer->{singer.Name} to quartet->{this.Name} cause quartet already more than 3 members");
        }
        Singers.Add(singer);
    }
}

public class MyFancyClass {
    private readonly Context _context;

    public MyFancyClass(Context context) {
        _context = context;
    }

    public Quartet DoWhatEverWithQartet(string name) {
        var myQuartet = _context.Quartets.FirstOrDefault(e => e.Name == name);
        foreach (var singer in myQuartet.Singers) {
            // Do whatever logic with singer
        }
        return myQuartet;
    }

    public void DoWhatEverLogicWithBassOfQuartet(string name) {
        var myQuartet = _context.Quartets.FirstOrDefault(e => e.Name == name);
        var bass = myQuartet.GetByType(SingerType.Bass);
        // Do whatever logic with bass
    }
}

public enum SingerType {
    Unknown = 0,
    Bass = 1,
    Bariton = 2,
    Lead = 3,
    Tenor = 4,
    Bullshit = 5,
    WhatEver = 6,
}

public class Context : DbContext {

    public IDbSet<Singer> Singers { get; set; }
    public IDbSet<Quartet> Quartets { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Configurations.Add(new QuartetConfiguration());
        base.OnModelCreating(modelBuilder);
    }
}

public class QuartetConfiguration : EntityTypeConfiguration<Quartet> {
    public QuartetConfiguration() {
        HasKey(e => e.Id);
        HasMany(e => e.Singers).WithRequired(e => e.Quartet).WillCascadeOnDelete(false);
    }
}

在这种情况下,您可以限制歌手四重奏在 BL 级别上的数量,并且您可以迭代四重奏中的所有歌手。

于 2018-04-19T07:12:04.427 回答