7

Solo quiero saber las mejores prácticas sobre cómo escribir métodos de repositorio. El problema es decidir escribir repositorio en cuyo contexto no tiene carga diferida. ¿Cómo nombras tu método si es GetById pero no está claro qué las navegaciones incluyeron en la entidad.Patrón de repositorio y propiedades de navegación

Así que estoy pensando en escribir nombres de métodos como GetUserByIdIncludedPosts ¿O es mejor utilizar el contexto de carga lenta activada?

Si escribo las propiedades incluidas en los nombres de los métodos, los nombres de los métodos largos serán realmente molestos para algunas propiedades de navegación.

Respuesta

2

El uso del patrón de repositorio no significa que no podrá usar la carga diferida. Todavía puede devolver la entidad que podrá cargar sus entidades relacionadas de forma perezosa. El único requisito es que DbContext utilizado para cargar la entidad debe estar "vivo".

Pero vamos a echar un vistazo en la definición de repositorio Martin Fowler:

Un repositorio de media entre las capas de dominio y de asignación de datos, actuando como un objeto de dominio colección en memoria. Los objetos del cliente construyen especificaciones de consulta declarativamente y los presentan al Repositorio para satisfacción con . Los objetos pueden ser añadidos a y se retiran del repositorio, como que pueden partir de una simple colección de objetos , y el código de mapeo encapsulado por el repositorio llevar a cabo las operaciones apropiadas detrás de las escenas. Conceptualmente, un Repositorio encapsula el conjunto de objetos persistidos en un almacén de datos y las operaciones realizadas sobre ellos, proporcionando una vista más orientada a objetos de la capa de persistencia. El repositorio también admite el objetivo de logrando una separación limpia y dependencia unidireccional entre el dominio y las capas de mapeo de datos.

Creo que la parte interesante es: cliente objetos construir especificaciones de consulta de forma declarativa, y someterlos a depósito para la satisfacción. También el repositorio generalmente se usa para proporcionar raíces agregadas. Por lo tanto, siempre proporcionará la raíz completa (no siempre es posible) o satisfará la declaración mencionada y definirá la carga ansiosa fuera del repositorio por el método de extensión Include en IQueryable. Por eso, nunca necesitará métodos especializados como GetUserByIdIncludeSomething.

Si desea repositorio de usuarios comenzar con este método para todas las consultas:

public interface IRepository<T> 
{ 
    IQueryable<T> GetQuery(); 
} 

BTW. No creo que un usuario sea una raíz agregada para las publicaciones. En tal caso, la mayoría de las aplicaciones tendrán solo una única raíz agregada: un usuario.

Editar:

pequeña aclaración: IQueryable por defecto no proporciona Include método.Se proporciona como método de extensión en el ensamblado CTP5, pero si lo usa hará que su capa superior dependa de EntityFramework.dll. Es algo que generalmente no desea (la razón por la que está usando el repositorio). Entonces, el camino a seguir es definir su propio método de extensión envolviendo la extensión proporcionada en el ensamblaje con su repositorio.

+0

No haga esto si desea mantener excepciones relacionadas con datos dentro de su capa de datos. Como la carga diferida se ejecutará en una capa más alta que la que firmarían los directores de arquitectura de cebolla. llevando a todo tipo de comportamiento erróneo. También hay otra razón, simplemente google 'repositorio patrón IQueryable' si desea observar la apasionante argumentación sobre este tema. – Shadetheartist

2

Estoy utilizando el siguiente en mi clase base repositorio para permitir la recuperación de las entidades junto con una lista especificada por el usuario de dependencias/relaciones:

protected DbSet<T> Objects { get; private set; } 
protected YourDatabaseContext Context { get; private set; } 

public virtual T GetByID(int id, params string[] children) 
{ 
    if(children == null || children.Length == 0) 
    { 
     return Objects.SingleOrDefault(e => e.ID == id); 
    } 
    DbQuery<T> query = children.Aggregate<string, DbQuery<T>>(Objects, (current, child) => current.Include(child)); 
    return query.SingleOrDefault(e => e.ID == id); 
} 

el código utiliza EF4/CTP5 y por lo tanto utiliza Db * Clases , pero es trivial convertir de nuevo a las clases normales de EF4 (por ejemplo, ObjectSet en lugar de DbSet).

Esto se usaría así:

var product = productsRepository.GetByID(42, "Category", "Orders.OrderLines"); 

que se vendería un producto con la categoría y las Órdenes de población, así como todas las órdenes que sus OrderLines ansiosamente cargados.

Cuestiones relacionadas