Я придумал идею, основанную на этой статье , в которой используется Entity Framework, но его было не слишком сложно перевести на классы LinqToSql.
Сначала я настроил класс ViewModel,Вам нужно будет хранить там больше информации, кроме объекта SystemFailureProblem
, например, информацию, относящуюся к коллекции SystemFailureType
, назначенной для этой проблемы.
public class SystemFailureProblemTypeViewModel
{
public int TypeID { get; set; }
public string TypeDescription { get; set; }
public bool Assigned { get; set; }
}
Далее я создал логику дляРедактировать действия (GET и POST).В методе GET вы узнаете, какие типы в настоящее время выбраны для проблемы (из таблицы xSystemFailureProblemToType), и создадите ViewModel, используя эти данные.Эта ViewModel передается в View вместе с объектом SystemFailureProblem
.
public ActionResult Edit(int id)
{
SystemFailureProblem problem = (from p in context.SystemFailureProblems
where p.ID == id
select p).Single();
PopulateSystemFailureProblemData(problem);
return View(problem);
}
public void PopulateSystemFailureProblemData(SystemFailureProblem problem)
{
// get all failure types
var allTypes = from t in context.SystemFailureTypes select t;
// get al types joined with this problem using cross table
var problemTypes = from x in context.xSystemFailureProblemToTypes
join t in context.SystemFailureTypes on x.SystemFailureTypeID equals t.ID
where x.SystemFailureProblemID == problem.ID
select t;
// construct view model collection
List<SystemFailureProblemTypeViewModel> viewModel = new List<SystemFailureProblemTypeViewModel>();
foreach (var type in allTypes)
{
viewModel.Add(new SystemFailureProblemTypeViewModel
{
TypeID = type.ID,
TypeDescription = type.Description,
Assigned = problemTypes.Contains(type)
});
}
ViewBag.Types = viewModel;
}
В методе POST мы получаем параметр string [], который сообщает нам, какие флажки были отмечены.Это список SystemFailureType
идентификаторов.Просмотрите все SystemFailureType
в базе данных, определите, какие из них выбраны / не выбраны, и соответствующим образом обновите таблицу xSystemFailureProblemToType.
[HttpPost]
public ActionResult Edit(int id, FormCollection collection, string[] selectedTypes)
{
SystemFailureProblem problem = (from p in context.SystemFailureProblems
where p.ID == id
select p).Single();
// get all types joined with this problem using cross table
var problemTypes = from x in context.xSystemFailureProblemToTypes
join t in context.SystemFailureTypes on x.SystemFailureTypeID equals t.ID
where x.SystemFailureProblemID == problem.ID
select t;
problem.FailureTypes = problemTypes.ToList<SystemFailureType>();
if (TryUpdateModel(problem, "", null, new string[] { "Types" }))
{
try
{
// loop through all types in the system
foreach (var failureType in context.SystemFailureTypes)
{
// determine if checkbox for current type was checked
if (selectedTypes.Contains(failureType.ID.ToString()))
{
// if no joining record exists (type not previously selected), create a joining record
if (!problemTypes.Contains(failureType))
{
context.xSystemFailureProblemToTypes.InsertOnSubmit(
new xSystemFailureProblemToType
{
SystemFailureProblemID = problem.ID,
SystemFailureTypeID = failureType.ID
});
}
}
else
{
// if type was unchecked but joining record exists, delete it
if (problemTypes.Contains(failureType))
{
xSystemFailureProblemToType toDelete = (from x in context.xSystemFailureProblemToTypes
where x.SystemFailureProblemID == problem.ID &&
x.SystemFailureTypeID == failureType.ID
select x).SingleOrDefault();
context.xSystemFailureProblemToTypes.DeleteOnSubmit(toDelete);
}
}
}
context.SubmitChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
PopulateSystemFailureProblemData(problem);
return View(problem);
}
Наконец, я настроил View.Этот код создаст 3 столбца флажков, каждый из которых имеет значение SystemFailureType
ID, которое он представляет.
<div class="editor-field">
<table>
<tr>
@{
int cnt = 0;
List<SystemFailures.Data.SystemFailureProblemTypeViewModel> types = ViewBag.Types;
foreach (var type in types) {
if (cnt++ % 3 == 0) {
@: </tr> <tr>
}
@: <td>
<input type="checkbox"
name="selectedTypes"
value="@type.TypeID"
@(Html.Raw(type.Assigned ? "checked=\"checked\"" : "")) />
@type.TypeDescription
@:</td>
}
@: </tr>
}
</table>
</div>
Возможно, он не самый эффективный, но я думаю, что он эффективно решает самые сложные части вашей проблемы.Дайте мне знать, если я что-то пропустил!