Entity Framework 6: How to map array elements to table columns

c# ef-code-first-mapping entity-framework-6

Question

The lack of an existing query with a solution to this conceptual inquiry startled me. Maybe I just didn't use the appropriate search terms.]

Think about a "Singer" entity type that has certain unique attributes. Next, imagine an entity type "Quartet" with precisely four Singers allocated to the quartet's roles of "Tenor," "Lead," "Baritone," and "Bass."

The easiest method to model this code initially is to just add four Vocalist navigation attributes with the names of the quartet's four singer roles to the Quartet entity class. As a result, we would have a one-to-four link between a Quartet table and a Singers database with four rows of foreign keys referencing the Quartet. This is not terrible and it works, however it causes some discomfort later in the programme.

Numerous actions would either need to be performed for each of the four singers individually or just one of the singers would need to be the subject of conditional queries, based on the value of an external enum that specifies which singer to act on.

Ideally, I'd want to have an array of Singers with a fixed size of four, whose members directly map to the enum values so that I could loop through the array or go straight to a particular element depending on the enum, rather than four distinct Singer navigation properties.

However, it doesn't appear like EF with SQL Server can model this adequately.

How can I get what I need done here?

1
0
4/14/2018 7:28:15 AM

Popular Answer

Consider the following code example:

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);
    }
}

In that instance, you may iterate through every singer in the quartet and you have a limit on how many singers the quartet can have at the BL level.

1
4/19/2018 7:12:04 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow