Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

157
Views
¿Por qué no hay un método AddRange/RemoveRange en la interfaz IDbSet en la Entidad 6?

En Entity Framework 6 se ha introducido el método AddRange. Es excelente para inserciones grandes porque el método DbSet.Add siempre activa DetectChanges, lo que ralentiza extremadamente el proceso. Solo quería usar un código existente basado en la interfaz IDbSet cuando me di cuenta de que no tiene el método AddRange. Solo existe en la clase DbSet.

Busqué en Google un poco y encontré esta discusión: http://forums.asp.net/t/1978828.aspx?Why+is+there+no+AddRange+method+for+System+Data+Entity+IDbSet+T+ - pero no hay una conclusión clara sobre la razón por la cual el método AddRange no existe en la interfaz IDbSet.

¿Es un error o hay alguna buena razón para que no esté allí? ¿Algunas ideas?

ACTUALIZAR

Aquí https://entityframework.codeplex.com/workitem/2781 Microsoft me dio una respuesta:

Esto es por diseño. El enfoque de la interfaz no era bueno para DbSet porque agregar miembros rompe las aplicaciones existentes que implementan la interfaz.

Dado que queremos poder agregar miembros a DbSet, cambiamos a un enfoque de clase base donde DbSet es una clase base que puede simular o heredar directamente.

Aquí hay algunos enlaces que muestran cómo usar DbSet en lugar de IDbSet:

https://msdn.microsoft.com/en-us/data/dn314429

https://msdn.microsoft.com/en-us/data/dn314431

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

De las notas de la reunión de diseño de Entity Framework, el 16 de mayo de 2013 :

El equipo reconoció el potencial para romper cambios:

Las clases DbSet (genéricas y no genéricas) heredan de una interfaz IDbSet (genérica o no genérica). IDbSet está diseñado solo para crear dobles de prueba, ya sean simulacros o falsificaciones.

Sin embargo, en EF6, DbSet ha cambiado de cuatro maneras que, si se reflejan en cambios equivalentes para IDbSet, serían cambios importantes:

  • FindAsync añadido
  • AddRange/RemoveRange añadido
  • El tipo de devolución local cambió a DbLocalView (este cambio se puede revertir de todos modos)

Discutieron un montón de posibles cambios en detalle, pero finalmente decidieron evitar el cambio importante y "hacer que DbSet sea más simulable":

La decisión fue hacer DbSet más simulable. Sin embargo, no obsoletaremos IDbSet porque esto crearía trabajo para aquellos que actualmente usan IDbSet que no necesitan usar los nuevos miembros. Agregaremos una guía a IDbSet que indique que el uso de DbSet es el camino a seguir para el nuevo código y, según los comentarios, podemos optar por dejar obsoleto a IDbSet en una versión futura.

Y si observa el código de IDbSet , agregaron comentarios en la parte superior de la interfaz:

IDbSet originalmente estaba destinado a permitir la creación de dobles de prueba (simulacros o falsificaciones) para DbSet. Sin embargo, este enfoque tiene problemas en el sentido de que agregar nuevos miembros a una interfaz rompe el código existente que ya implementa la interfaz sin los nuevos miembros.

Por lo tanto, a partir de EF6, no se agregarán nuevos miembros a esta interfaz y se recomienda usar DbSet como clase base para los dobles de prueba.

over 4 years ago · Santiago Trujillo Report

0

Esto definitivamente no es un error y se hace así por diseño. Es difícil responder a este tipo de preguntas sin ser un desarrollador de la biblioteca .NET, pero supongo que querían mantener las interfaces simples. Tal vez alguien en el equipo de .NET vea esto y comente. Los problemas de compatibilidad con versiones anteriores estarán vinculados a la interfaz/implementación concreta, que definitivamente también es una posibilidad en este escenario. Sin embargo, este razonamiento probablemente no se trasladará a por qué IList/ICollection no los define.

Un argumento es que al agregar AddRange (así como RemoveRange/InsertRange) a la interfaz, obliga al implementador a definir esos métodos. Las interfaces deben ser simples y fáciles de definir. Los métodos AddRange, etc. realmente solo deberían existir en colecciones concretas donde puede ver mejoras de rendimiento. Por ejemplo, una lista puede optimizar su AddRange aumentando adecuadamente su capacidad interna, etc. Donde un simple bucle sobre los elementos y llamar a Add puede ser más costoso (por ejemplo, a través de un método de extensión).

Probablemente hagan esto por la misma razón por la que IList, ICollection, etc. no tienen AddRange en la interfaz directamente, pero sí en las implementaciones concretas.

Hay una solución para esto, y es abstraer tanto la interfaz como la clase concreta usando su propia interfaz/clase. Puede darle a su interfaz un AddRange y extender DBSet/implementar su interfaz en otra clase. Esto puede o no funcionar dependiendo de cómo esté usando IDBSet/DBSet en su código. Aunque, un poco de refactorización puede hacer que esto funcione. Algo como esto --

 public class MyDbSet<TEntity> : DbSet<TEntity>, IMyDbSet<TEntity> where TEntity : class { } public interface IMyDbSet<TEntity> : IDbSet<TEntity> where TEntity : class { IEnumerable<TEntity> AddRange(IEnumerable<TEntity> items); }

Ahora, solo puede usar IMyDbSet en su código. No es necesario implementar AddRange, ya que ya está implementado al extender DbSet. Los métodos externos que solo aceptan IDbSet/DbSet aún deben aceptar MyDbSet/IMyDbSet.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!