Ivan Aramazov
Ivan Aramazov

Reputation: 167

Linq Column name as variable

I have table with three columns: Subject1, Subject2, Subject3. And I have the following query:

Schedule update = (from s in _db.Information
                   where s.Id == Id
                   select s).Single();

update.Subject2= subjectStatus;  
_db.SaveChanges(); 

How can I replace the column name with variable? Something like this:

string customColumnName = "Subject" + selectedNumber;
update.customColumnName = subjectStatus;

The variable selectedNumber is set in another method.

Upvotes: 2

Views: 230

Answers (1)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112352

The problem arises, because your db schema is not fully normalized. A fully normalized approach would be to extract the subject into another table and to create a 1-to-n relation. But I agree that sometimes, normalization pushed to its limits can add quite a bit of complexity that might seem exaggerated.

If you don't want to change your schema, you could wrap your Subject properties into an indexer

public class Schedule
{
    public string Subject1 { get; set; }
    public string Subject2 { get; set; }
    public string Subject3 { get; set; }

    public string this[int index]
    {
        get {
            switch (index) {
                case 1: return Subject1;
                case 2: return Subject2;
                case 3: return Subject3;
                default: return null;
            }
        }
        set {
            switch (index) {
                case 1: Subject1 = value; break;
                case 2: Subject2 = value; break;
                case 3: Subject3 = value; break;
                default: break;
            }
        }
    }

Can be used like this:

update[selectedNumber] = "Subject" + selectedNumber;

The downside is that this works only for one single property group, since you can only have one indexer with this signature; however, you could expand it to include the property name if you have more than one numbered property.

public string this[string propertyName, int index]

C# does not have named indexers; however, you can create one by the intermediary of an accessor. In the following example I use a nested class for this purpose.

public class SubjectAccessor
{
    private readonly Schedule _schedule;

    public SubjectAccessor(Schedule schedule) { _schedule = schedule; }

    public string this[int index]
    {
        get {
            switch (index) {
                case 1: return _schedule.Subject1;
                case 2: return _schedule.Subject2;
                case 3: return _schedule.Subject3;
                default: return null;
            }
        }
        set {
            switch (index) {
                case 1: _schedule.Subject1 = value; break;
                case 2: _schedule.Subject2 = value; break;
                case 3: _schedule.Subject3 = value; break;
                default: break;
            }
        }
    }
}

public SubjectAccessor Subject { get; }

public Schedule()
{
    Subject = new SubjectAccessor(this);
}

Can be used like this:

update.Subject[selectedNumber] = "Subject" + selectedNumber;

Upvotes: 1

Related Questions