Question

I want to make a function template that changes in only one meaningful way. I'm currently creating individual ActionResult's to change user settings in my MVC application. There are a lot of options and I'm trying tired of writing out a new ActionResult method for every single checkbox so I need a little direction on how to access and set values where I do not explicitly set an objects member with dot notation.

Here's an example of a checkbox ActionResult currently:

public ActionResult ChangeActivityShowNewProduct(bool value)
{
    var _id = Convert.ToInt32(Session["ID"]);
    var dataContext = new SecurityDataContext();
    var x = from c in dataContext.UserSettings
            where c.UserID == _id
            select c;

    foreach (var setting in x)
    {
        setting.ActivityShowNewProduct = value;
    }

    dataContext.SubmitChanges();

    Session["ActivityShowNewProduct"] = value;

    return Json(Session["ActivityShowNewProduct"], JsonRequestBehavior.AllowGet);
}

Another example would be very similar but possibly called "ChangeActivityShowNewUser" where the only difference in the underlying code would be in the foreach loop having setting.ActivityShowNewUser instead (as well as the session variables but I'm not worried about assigning those).

Is there anyway to set the setting's member with a string? Perhaps out of a foreach loop? I'm not very versed with the IQueryable object yet so I'm not too sure where to start looking. Any reference materials would be much appreciated!

UPDATE


There we go. It works but it's a bit repetitive, I'm working on that. Posting for others and/or critique. Thanks guys.

Func<int, bool, Action<UserSetting>, bool> CheckBoxChanger = (i, b, v) =>
{
    var _id = i;

    var dataContext = new SecurityDataContext();
    var x = from c in dataContext.UserSettings
            where c.UserID == _id
            select c;

    foreach (var setting in x)
    {
        v(setting);
    }

    dataContext.SubmitChanges();

    return b;
};

public ActionResult CheckBoxSettingChange(Action<UserSetting> valueSetter, bool result, string SessionName)
{
    Session[SessionName] = CheckBoxChanger(Convert.ToInt32(Session["ID"]), result, valueSetter);

    return Json(Session[SessionName], JsonRequestBehavior.AllowGet);
}

public void DoIt(string name, bool val)
{
    switch (name)
    {
        case "ChangeActivityShowNewProduct":
            CheckBoxSettingChange(setting => setting.ActivityShowNewProduct = val, val, name);
            break;

        // ... etc etc etc
    }
}
Was it helpful?

Solution

By the time you're executing the foreach loop it's no longer just a query; it has been materialized into a result.

You can just have this method accept a method which takes the item and sets that value. Then you can just call that method on each item:

public ActionResult ChangeActivityShowNewProduct(Action<UserSetting> valueSetter)
{
    //...
    foreach (var setting in x)
        valueSetter(setting);
    //...
}

Then to call it you would have something like:

ChangeActivityShowNewProduct(setting => setting.ActivityShowNewProduct = false);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top