c# - Entity Framework - 为什么选择导航属性?

标签 c# .net entity-framework navigation-properties

我有一个如下所示的基本存储库:

public class BaseRepository<T> : IBaseRepository<T> where T : class
{
    private DbContext _context;
    private IDbSet<T> _dbSet;

    protected DbContext Context
    {
        get
        {
            if (_context == null)
            {
                EFUnitOfWork currentUnitOfWork = (EFUnitOfWork)UnitOfWork.Current;
                _context = currentUnitOfWork.Context;
            }

            return _context;
        }
    }

    protected IDbSet<T> DbSet
    {
        get
        {
            if (_dbSet == null)
            {
                _dbSet = Context.Set<T>();
            }

            return _dbSet;
        }
    }

    public void Add(T entity)
    {
        DbSet.Add(entity);
    }

    public void Attach(T entity)
    {
        DbSet.Attach(entity);
    }

    public void Delete(T entity)
    {
        DbSet.Remove(entity);
    }

    public void Update(T entity)
    {
        Context.Entry(entity).State = System.Data.EntityState.Modified;
    }             

    public IQueryable<T> Get(string[] includes=null)
    {
        IQueryable<T> set = DbSet;
        if (includes != null)
        {
            foreach (string include in includes)
            {
                set = set.Include(include);
            }
        }
        return set;
    }
  1. User user = _usersRepository.Get().SingleOrDefault(u => u.Username == "gigi"); 这会返回没有 Roles 属性的用户,这是可以的。

  2. User user = _usersRepository.Get(new string[] { "Roles" }).SingleOrDefault(u => u.Username == "gigi");这将返回用户和 Roles 属性,这是可以的。

  3. List<User> users = _usersRepository.Get().Where(u => u.Username.StartsWith("gi")).ToList();

  4. List<User> users = _usersRepository.Get(new string[] { "Roles" }).Where(u => u.Username.StartsWith("gi")).ToList();

查询 3 和 4 都返回具有 Roles 属性的用户列表。 为什么查询 3 返回 Roles?

LE:这是调用,我在上下文处理后检查用户集合。

            List<User> users = _usersRepository.Get().Where(u => u.Username.StartsWith("gi")).ToList();
            UnitOfWork.Current.Dispose();

LE2:我分别做了同样的事情:

  1.         List<User> users;
            using (MyEntities ctx = new MyEntities ())
            {
                users= ctx.Users.ToList();
            }
    
  2.             List<User> users;
                using (MyEntities ctx = new MyEntities ())
                {
                    users= ctx.Users.Include("Roles").ToList();
                }
    

在第一种情况下,角色未加载,在第二种情况下,角色未加载,这是可以的。

我没有看到我在存储库示例中做错了什么。

LE3:这是工作单元

    public class UnitOfWork
    {
        private const string HTTPCONTEXTKEY = "Repository.Key";

        private static IUnitOfWorkFactory _unitOfWorkFactory;
        private static readonly Hashtable _threads = new Hashtable();

        public static IUnitOfWork Current
        {
            get
            {
                IUnitOfWork unitOfWork = GetUnitOfWork();

                if (unitOfWork == null)
                {
                    _unitOfWorkFactory = ObjectFactory.GetInstance<IUnitOfWorkFactory>();
                    unitOfWork = _unitOfWorkFactory.Create();
                    SaveUnitOfWork(unitOfWork);
                }

                return unitOfWork;
            }
        }

        private static IUnitOfWork GetUnitOfWork()
        {
            if (HttpContext.Current != null)
            {
                if (HttpContext.Current.Items.Contains(HTTPCONTEXTKEY))
                {
                    return (IUnitOfWork)HttpContext.Current.Items[HTTPCONTEXTKEY];
                }

                return null;
            }
            else
            {
                Thread thread = Thread.CurrentThread;
                if (string.IsNullOrEmpty(thread.Name))
                {
                    thread.Name = Guid.NewGuid().ToString();
                    return null;
                }
                else
                {
                    lock (_threads.SyncRoot)
                    {
                        return (IUnitOfWork)_threads[Thread.CurrentThread.Name];
                    }
                }
            }
        }

        private static void SaveUnitOfWork(IUnitOfWork unitOfWork)
        {
            if (HttpContext.Current != null)
            {
                HttpContext.Current.Items[HTTPCONTEXTKEY] = unitOfWork;
            }
            else
            {
                lock (_threads.SyncRoot)
                {
                    _threads[Thread.CurrentThread.Name] = unitOfWork;
                }
            }
        }
    }

最佳答案

EF 将尝试填充尽可能多的属性。

如果您已将数据库行加载到 DbContext 中,EF 将在 DbContext 的生命周期内记住该行的数据。

然后,当您加载引用该行的任何实体时,EF 将使用或不使用 Include 子句填充该属性。

在您的例子中,您正在查询 2 中加载(部分)角色表。
当您运行查询 3 时,这些行将在不包含 Include 的情况下填充,因为它们已经位于 DbContext 中。

关于c# - Entity Framework - 为什么选择导航属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12554577/

相关文章:

c# - .net 图表控件 : retain series colors when adding and removing other series?

entity-framework - 序列化 Azure 缓存的 Entity Framework 对象

c# - 异步编程的类型转换错误

c# - Nlog 和自定义级别

c# - 读取文件时出现 OutOfMemoryException

c# - "Non-Click"行为在什么地方适合 MVVM 应用程序?

c# - 有没有办法在后台线程上建立 TreeView 控件?

.net - 修复Youtube URL RegEx(.NET ReGex引擎语法)

c# - DocumentSaved 事件永远不会引发

.net - Entity Framework 插入需要选择权限