简体   繁体   English

如何使用存储库模式访问EF中的导航属性

[英]How to access navigation properties in EF using repository pattern

Context: ASP.NET web application 上下文:ASP.NET Web应用程序

The Base Repository (abstract class) implements the needed base functionality from which all other repositories inherit: ie -PersonRepo -AddressRepo 基本存储库(抽象类)实现了所有其他存储库都将从其继承的必需的基本功能:即-PersonRepo -AddressRepo

EDIT: Where do you place the code which queries several db tables and some of them are not directly related as navigation property in the respective repository? 编辑:您将查询几个数据库表的代码放在何处,而其中一些与导航属性没有直接关系,分别位于相应的存储库中?

Now, what is the best way to access the navigation properties? 现在,访问导航属性的最佳方法是什么? It is very cumbersome when using the repository pattern. 使用存储库模式时非常麻烦。 If there is not a convenient solution for this, I will stick to my old DAL layer with everything inside and work with DbContext directly. 如果没有方便的解决方案,我将保留所有内部内容并保留旧的DAL层,然后直接使用DbContext。

I just came up with a temporary solution for accessing navigation properties in my PersonRepository implementation: 我只是想出一个临时解决方案来访问我的PersonRepository实现中的导航属性:

public Person InsertNewPersonWithAddress(Person p, Address addr)
        {
            this.Insert(p); // insert person
            var ar = new AddressRepository(this.ctx);
            ar.Insert(addr);  // insert address
            this.Addresses(p).Add(addr);  // add address to person

            return p;
        }

        /* Navigation Properties */ 
        ICollection<Address> Addresses(Person p)
        {
            return ctx.Entry<Person>(p).Collection<Address>("Addresses").CurrentValue;
        }

Base Repository class implements the following interface 基本存储库类实现以下接口

public interface IRepository<T> where T : class
    {
        IQueryable<T> All();
        IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
        T Insert(T entity);
        IEnumerable<T> InsertMultiple(IEnumerable<T> items);
        T Delete(T entity);
        IEnumerable<T> DeleteMultiple(IEnumerable<T> items);
        T Update(T entity);
        IEnumerable<T> UpdateMultiple(IEnumerable<T> items);
        void Save();
    }

DB-Design: DB-设计:

Person --> PersonAddress(junction table) <-- Address 人员->人员地址(连接表)<-地址

Any intelligent solution for this problem? 任何智能解决此问题的方法?

You are thinking about this the wrong way. 您在想这是错误的方式。 The navigation property is a property of the Entity, not a property of the Repository. Navigation属性是Entity的属性,而不是Repository的属性。 You don't need to instantiate a Repository for the navigation property, it can be added directly to the Entity. 您无需为导航属性实例化存储库,可以将其直接添加到实体。

public Person InsertNewPersonWithAddress(Person p, Address addr)
{
    p.Address = addr;
    this.Insert(p); // insert person

    return p;
}

Now, if you are inserting a new Person but want it attached to an existing Address (rather than inserting a new copy of both), you can expose the AddressId FK as a property on the Person Entity, and pass in the FK value to do the link. 现在,如果要插入新的Person但希望将其附加到现有Address (而不是插入两者的新副本),则可以将AddressId FK公开为Person Entity上的属性,并传递FK值来执行链接。 In either case, it's not necessary for this Repository to need access to the other. 无论哪种情况,此存储库都不需要访问另一个存储库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM