Scott 混合理论
Scott 混合理论

Reputation: 2332

How to get a single object by LINQ? ERROR: The result of a query cannot be enumerated more than once

My code like this:

    private void BindGvUsersInRole ()
    {
        var aRole =
            (from aspnet_Roles rol
                 in _allRoles
            where rol.RoleId.ToString() == ddlRoles.SelectedValue
            select rol).SingleOrDefault();

        this.gvUsersInRole.DataSource = aRole.aspnet_Users;
        this.gvUsersInRole.DataBind();
    }

I got an error on the last line:

Exception Details: System.InvalidOperationException: The result of a query cannot be enumerated more than once.

then I amend the function like this(thanks @VitaliyKalinin):

private void BindGvUsersInRole ()
{
    Guid  roleID=new Guid(ddlRoles.SelectedValue);

    var users =
    (
        from aspnet_Roles rol in _allRoles
        from u in rol.aspnet_Users
        where rol.RoleId == roleID
        select u
    ).ToList();

    this.gvUsersInRole.DataSource = users;
    this.gvUsersInRole.DataBind();
}

STILL SAME ERROR!!!!

what happens!?!?

the "aspnet_Users" property :

    /// <summary>
    /// 没有元数据文档可用。
    /// </summary>
    [XmlIgnoreAttribute()]
    [SoapIgnoreAttribute()]
    [DataMemberAttribute()]
    [EdmRelationshipNavigationPropertyAttribute("realtydbModel", "aspnet_UsersInRoles", "aspnet_Users")]
    public EntityCollection<aspnet_Users> aspnet_Users
    {
        get
        {
            return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<aspnet_Users>("realtydbModel.aspnet_UsersInRoles", "aspnet_Users");
        }
        set
        {
            if ((value != null))
            {
                ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<aspnet_Users>("realtydbModel.aspnet_UsersInRoles", "aspnet_Users", value);
            }
        }
    }

Upvotes: 2

Views: 955

Answers (5)

Memet Olsen
Memet Olsen

Reputation: 4608

var aRole = _allRoles.Single(x=>x.RoleId.ToString() == ddlRoles.SelectedValue);

Correct me if I'm wrong but this one is also a possible option

Upvotes: 1

Duane Theriot
Duane Theriot

Reputation: 2185

private void BindGvUsersInRole ()
{
    var roleID = new Guid(ddlRoles.SelectedValue);

    var users = (from rol in _allRoles
                 where rol.RoleId == roleID
                 select rol.aspnet_Users).ToList();

    this.gvUsersInRole.DataSource = users;
    this.gvUsersInRole.DataBind();
}

Upvotes: 0

Arnaud F.
Arnaud F.

Reputation: 8452

You can do :

var aRole = _allRoles.ToList().FirstOrDefault(rol => rol.RoleId.ToString() == ddlRoles.SelectedValue);

Upvotes: 1

Vitaliy Kalinin
Vitaliy Kalinin

Reputation: 1871

Something like this will do:

private void BindGvUsersInRole () 
    { 
        var aUsers = 
            (from aspnet_Roles rol in _allRoles
from u in rol.aspnet_Users
            where rol.RoleId.ToString() == ddlRoles.SelectedValue 
            select u).ToList(); 

        this.gvUsersInRole.DataSource = aUsers; 
        this.gvUsersInRole.DataBind(); 
    } 

Upvotes: 0

ntziolis
ntziolis

Reputation: 10221

You can use Single or SingleOrDefault() todo this:

// parse the string `ddlRoles.SelectedValue` into the appropriate type as `roleID`
var roleID = ParseRoleID(ddlRoles.SelectedValue);
var aRole = (from rol in aspnet_Roles.Include("aspnet_Users")
            where rol.RoleId == roleID 
            select rol).Single();

However this will throw an exception if there is more than one entity returned. If you just want the first entity that matches the case you can use First()or FirstOrDefault():

var roleID = ParseRoleID(ddlRoles.SelectedValue);
var aRole = (from rol in aspnet_Roles.Include("aspnet_Users")
            where rol.RoleId == roleID 
            select rol).First();

The OrDefaultversions of these methods make sure you don't get an exception if there is no match. It will return null instead.

Also:
Rather than using ToString() on the RoleId parse the ddlRoles.SelectedValue into the appropriate type before you use it in the LINQ query since some methods (ToString() is one of them) are not supported within a LINQ query that executes against a DB.

Upvotes: 3

Related Questions