2

我有一个User分配给一个Client. 拉出User对象时,我将Client对象作为它的一部分。简单的。

这在登录时可以正常工作。无论我以谁身份登录,该User对象都有一个。Client

但是,使用与登录时完全相同的方法获取User,通过管理菜单对其进行编辑,Client有时是null.

有时会说:

1) 在 Firefox 中 - 当试图查看大多数(但不是全部)用户(和我自己)的详细信息时,附加Client到. 由于实际存在,只有几个将是可见的。UsernullUsersClient

2) 在 Chrome 中 - 所有用户(我自己除外)都是可见的。只有在尝试查看我自己的用户时Client才会null.

我不明白; 两种浏览器都只是简单地访问相同的 URL,即/Users/EditGet/28,即使使用两种不同的方法 (GetByIdGetByUserName),它也提供了相同的结果——尽管无可否认,它们都使用了基本的 Get 函数:

编辑: BaseService 类一起而不是编辑。

internal CustomContext context;
internal DbSet<TEntity> dbSet;

public BaseService(CustomContext context)
{
    this.context = context;
    this.dbSet = context.Set<TEntity>();
}

public virtual IEnumerable<TEntity> Get(
    Expression<Func<TEntity, bool>> filter = null,
    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
    string includeProperties = "")
{
    IQueryable<TEntity> query = dbSet.Where(e => !e.Deleted);

    if (filter != null)
    {
        query = query.Where(filter);
    }

    foreach (var includeProperty in includeProperties.Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries))
    {
        query = query.Include(includeProperty);
    }

    return orderBy != null ? orderBy(query).ToList() : query.ToList();
}

我不确定为什么浏览器的选择会影响后端查询的结果。当然,无论我使用什么浏览器,它都应该Client返回User

我假设基本 Get 方法可能存在基本错误,但它并不能解释我所看到的行为......

如果有人能对此有所了解,我将不胜感激。

编辑 2:自定义上下文:

public class CustomContext : DbContext, ICustomContext
{
    public IDbSet<User> Users { get; set; }
    public IDbSet<Client> Clients { get; set; }
}
4

2 回答 2

0

我似乎问题源于我们存储当前登录的User.

当尝试检索另一个相同的User对象时,它也会失败并拉出Client.

仍然不太清楚为什么会这样。我有一些提示,它与Object State Manager和跟踪多个对象有关——尽管当前登录的User对象实际上并没有从数据库中提取......

然而,解决这个问题的方法是做一个简单的检查,看看User拉出的内容是否与当前登录的相同User,如果问题存在(即Clientnull)然后拉出Client并将其附加到User对象上。

private User GetUser(long id)
{
    var user = Services.UserService.GetById(id);
    if (user.Client == null && CurrentUser.Id == user.Id)
        user.Client = Services.ClientService.GetByClient(CurrentUser.Client);

    return user;
}

粗鲁,对于如何正确解决这个问题远非一个体面的答案,但它有效,并且所有Users 都可以再次完全编辑。

于 2013-06-14T09:11:44.777 回答
0

您可能还想从逗号分隔的包含列表中进行更改 - 这可能容易出现格式错误;您可以将其更改为 param 或类似这样的数组:

        public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
                                                    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
                                                    params string[] includeProperties) {

            var query = ((DbQuery<TEntity>)dbset);

            query = includeProperties.Aggregate(query, (q, s) => q.Include(s));

            query = query.Where(e => !e.IsDeleted);


            if (filter != null) {
                query = query.Where(filter);
            }                

            return orderBy != null ? orderBy(query).ToList() : query.ToList();
        }

我在想,如果它像您所说的那样依赖于浏览器,则可能存在一些字符串格式问题……无论如何都值得一试。

编辑:将查询更改回 DbQuery

EDIT2:修复是在as必须调用orInclude之前调用 to 。它看起来很随机的原因是,当没有过滤器时,在它们应该在的 DbSet/DbQuery 上调用了包含。WhereIncludeDbSetDbQuery

不容易发现,因为代码调用了IQueryable<T>.Include... 这不是开箱即用的标准。位于IncludeDbSet 或 DbQuery 上。

于 2013-06-05T16:18:16.650 回答