Linq Удалить поверх Присоединиться - PullRequest
1 голос
/ 06 мая 2009

У меня есть таблица вопросов, которая присоединяется к таблице решений. Решения связаны с вопросами, но чтобы удалить вопрос, я должен сначала удалить решения для этого вопроса, а затем удалить сам вопрос.

У меня есть запрос linq, который извлекает все решения для определенного вопроса, однако я не уверен, как выполнить удаление решений и, следовательно, затем удалить вопрос.

Вот код, который получает сообщения об ошибках перегрузки:

public static void DeleteSol(string qTextInput)
{
    ExamineDataContext dc = new ExamineDataContext();
    var matchedSol = from q in dc.Questions
                          where q.QuestionText.Contains(qTextInput)
                          join s in dc.Solutions
                          on q.QuestionID equals s.QuestionID
                          into qs // note grouping        
                          select new
                          {
                              solution = qs
                          };
    try
    {
        dc.Solutions.DeleteOnSubmit(matchedSol);
        dc.SubmitChanges();
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Ответы [ 3 ]

3 голосов
/ 06 мая 2009

Если у вас есть отношение внешнего ключа между вашими вопросами и решениями, просто установите его так, чтобы удаления распространялись (CASCADE ON DELETE). Таким образом, вам нужно только удалить вопрос, и решения автоматически удаляются из базы данных.

Использование отношения внешнего ключа также даст вам набор сущностей в вашей сущности Вопрос, который будет непосредственно загружать связанные сущности Решения и сделает его таким образом, чтобы вы могли избежать постоянной записи логики соединения. Вам нужно будет удалить и повторно добавить ваши сущности после добавления отношения внешнего ключа, чтобы дизайнер мог их поднять, или вы можете добавить ассоциацию вручную в конструкторе.

1 голос
/ 06 мая 2009

Я думаю, что использование Join является основной причиной проблемы. Попробуйте создать отображение в DBML между вопросами и предложениями, тогда вы сможете просто написать:

var questions = from q in Questions where q.QuestionText.Contains(qTextInput);
var solutions = questions.SelectMany(q => q.Solutions);
...
dc.Solutions.DeleteAllOnSubmit(solutions);
0 голосов
/ 06 мая 2009

Проблема в том, что matchedSol не относится к типу IEnumerable<Solution>. Я был бы удивлен, если бы ваш код даже компилировался.

Что вам нужно, так это (в примере используются объекты LINQ2Object, но это не имеет значения):

static void Main()
{
    var questions = new[]
                        {
                            new { QuestionID = 1, QuestionText = "ABCDEF" },
                            new { QuestionID = 2, QuestionText = "GHIJKL" },
                            new { QuestionID = 3, QuestionText = "ABCXYZ" },
                        };
    var solutions = new[]
                        {
                            new { QuestionID = 1, Solution = "P" },
                            new { QuestionID = 1, Solution = "Q" },
                            new { QuestionID = 2, Solution = "R" },
                            new { QuestionID = 3, Solution = "S" },
                            new { QuestionID = 3, Solution = "T" },
                            new { QuestionID = 4, Solution = "U" },
                        };
    var qTextInput = "ABC";
    var matchedSol = from q in questions
                     where q.QuestionText.Contains(qTextInput)
                     join s in solutions
                     on q.QuestionID equals s.QuestionID
                     select s;

    foreach (var solution in matchedSol)
    {
        Console.WriteLine("Solution " + solution.Solution +
                          " for question " + solution.QuestionID);
    }
}

Результат выражения LINQ можно перечислить с четырьмя решениями: P, Q, S и T. Это перечислимое можно передать вашему DeleteOnSubmit методу.

...