Why was the mistake "New transaction is not allowed"



  • I was wrong.

    New transaction is not allowed because there are other threads running in the session

    I couldn't find a reason for a few hours. There is a repository method that briefly makes the following (yes, redundant logic):

    return
        rc.Context.Chats.Include("Participants.User")
            .Where(m => m.Participants.Any(u => u.User.ID == userId))
            .Each(
                c =>
                    c.Name = String.Join(", ", 
                                c.Participants.Where(u => u.User.ID != userId).Select(s => s.User.Login)))
            .ToList();
    

    The method uses self-extension Each:

    public static IEnumerable<T> Each<T>(this IEnumerable<T> xs, Action<T> action)
    {
        if (xs != null)
            xs.Each((i, x) => action(x));
    
    return xs;
    

    }

    public static IEnumerable<T> Each<T>(this IEnumerable<T> xs, Action<int, T> action)
    {
    var e = xs.GetEnumerator();
    for (int i = 0; e.MoveNext(); i++)
    {
    action(i, e.Current);
    }
    return xs;
    }

    If, after the challenge of the repository method, any case-by-case action is inclined by the error described above. Looking for a solution, I added one extra. .ToList() after Where - and voila-- it's working.

    return
    rc.Context.Chats.Include("Participants.User")
    .Where(m => m.Participants.Any(u => u.User.ID == userId))
    .ToList()
    .Each(
    c =>
    c.Name = String.Join(", ",
    c.Participants.Where(u => u.User.ID != userId).Select(s => s.User.Login)))
    .ToList();

    However, I cannot yet understand the reason for such behaviour. Why on the direct call of an envelope? ToList() The flow covers the transaction and the attachment IQueryable to IEnumerablefollow-up and introduction ToList() - No?



  • New transaction is not allowed because there are other threads running in the session

    The mistake tells me you're trying to turn to rc.Context at the same time from two streams. And your code confirms that. DbContext needs to be created on every request. I mean, it's a trench. He runs the pattern "work medic."

    using(var context = new DbContext())
    {
       // ваши манипуляции с базой.
    }
    

    rc shall not contain a field Context but shall act as a factory at that time:

    using(var context = rc.CreateContext())
    {
       // ваши манипуляции с базой.
    }
    

    If you don't, try to do this:

    return rc.Context.Chats.Include("Participants.User")
        .Where(m => m.Participants.Any(u => u.User.ID == userId))
        .ToList()
        .Select(c =>
        {
           c.Name = String.Join(", ", c.Participants
                                       .Where(u => u.User.ID != userId)
                                       .Select(s => s.User.Login));
           return c;
        })
        .ToList();
    



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2