实体框架避免LazyLoading /已经打开DataReader问题

时间:2016-02-25 09:49:00

标签: c# mysql entity-framework lazy-loading union

如果联接查询连续多次运行,那么如果UserlistSection与起始字母一起存在,则每个字母都会得到Users个对象。 所以我得到这样的东西:

  • UserlistSection" A"
    • 用户
    • 用户
  • UserlistSection" H"
    • 用户
  • UserlistSection" Y"
    • 用户
    • 用户
    • 用户

但是查询会抛出异常

MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.

查询任务

public UserRepository(myDatabase database)
    {
        _database = database;
    }

public Task<ObservableCollection<User>> GetUserFriendsAsync(int id, string letter)
    {
        return Task.Factory.StartNew(() =>
        {
            try
            {
                var query1 = (from urs in _database.user_relationships
                              join u in _database.users on urs.relationship_user_from equals u.user_id
                              where urs.relationship_user_to == id
                                    && u.user_name.StartsWith(letter)
                                    && urs.relationship_status == 1
                              select new User
                              {
                                  Id = u.user_id,
                                  Username = u.user_name,
                                  AvatarByte = u.user_avatar,
                                  Gender = u.user_gender,
                                  GroupId = u.user_usergroup,
                                  LoginStatusId = u.user_loginstatus
                              });

                var query2 = (from urs in _database.user_relationships
                              join u in _database.users on urs.relationship_user_to equals u.user_id
                              where urs.relationship_user_from == id
                                    && u.user_name.StartsWith(letter)
                                    && urs.relationship_status == 1
                              select new User
                              {
                                  Id = u.user_id,
                                  Username = u.user_name,
                                  AvatarByte = u.user_avatar,
                                  Gender = u.user_gender,
                                  GroupId = u.user_usergroup,
                                  LoginStatusId = u.user_loginstatus
                              });

                // Union to get users via relationships (from - to and to - from)
                var queryUnion = query1.Union(query2).OrderBy(u => u.Username);

                return new ObservableCollection<User>(queryUnion);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("UserRepository - GetUserFriendsAsync" + ex);
                return null;
            }
        });
    }

我的对象/方法来创建集合

public class UserlistSection : ObservableObject
{
    #region Attributes

    private string _letter;
    private ObservableCollection<User> _users;

    #endregion Attributes

    public string Letter
    {
        get { return _letter; }
        set { Set(ref _letter, value); }
    }

    public ObservableCollection<User> Users
    {
        get { return _users; }
        set { Set(ref _users, value); }
    }
}

// -------------------------------------------------------------------------

 public async void UpdateFriendlistCollection()
    {
        IsLoading = true;
        Friendlist = new ObservableCollection<UserlistSection>();

        for (var c = 'A'; c <= 'Z'; c++)
        {
            try
            {
                var letter = c.ToString();
                var userCollection = await _userRepository.GetUserFriendsAsync(_userObj.Id, letter);

                if (userCollection.Count < 1) return;

                foreach (var friend in userCollection)
                {
                    friend.AvatarImage = friend.GetAvatarImgByPixel(200);
                }

                var section = new UserlistSection
                {
                    Letter = letter,
                    Users = userCollection
                };

                Friendlist.Add(section);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("FriendlistViewModel - UpdateFriendlistCollection: " + ex.Message);
            }
        }

        IsLoading = false;
    }

可能有更好的方法来构建查询,但我还无法弄清楚如何。如果有人能够看到我的错误以避免LazyLoading /解决异常,那就太好了。

如果我错过了一些解释,请告诉我们。

修改

当我这样添加MultipleActiveResultSets=True时,它会告诉我该关键字不支持?

<connectionStrings>
<add name="someDatabase"   connectionString="metadata=res://*/Repository.Database.SomeDatabase.csdl|res://*/Repository.Database.SomeDatabase.ssdl|res://*/Repository.Database.SomeDatabase.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=127.0.0.1;user id=someUser;persistsecurityinfo=True;password=somePassword;multipleactiveresultsets=True;database=someDatabase;&quot;" providerName="System.Data.EntityClient" />

System.ArgumentException: Keyword not supported.
Parametername: multipleactiveresultsets
bei MySql.Data.MySqlClient.MySqlConnectionStringBuilder.GetOption(String key)
bei MySql.Data.MySqlClient.MySqlConnectionStringBuilder.set_Item(String  keyword, Object value)

1 个答案:

答案 0 :(得分:2)

您应该在config中的connectionstring中启用MARS。

"MultipleActiveResultSets=True"添加到连接字符串。

更多info

修改

来自MSDN

  

在foreach(C#)或For Each期间调用Load方法时   (Visual Basic)枚举,实体框架尝试打开一个新的   数据阅读器。除非您启用了多个操作,否则此操作将失败   通过在。中指定multipleactiveresultsets = true来激活结果集   连接字符串。有关更多信息,请参阅使用多个活动   MSDN上的结果集(MARS)。您还可以加载查询结果   进入List集合,关闭数据阅读器并启用您   枚举集合以加载引用的实体

修改

对于MySQL,我找到了this。 Mayby它可以帮助你。

似乎MySQL不支持MARS。如果您可以更改MS SQL Server Express的数据库。或者更改ORM,例如NHibernate。