c# - tutorial - nhibernate vs entity framework
Consulta en referencia HasMany (2)
Como casi siempre, NHibernate tiene una respuesta para esto. Lo que estamos tratando de lograr aquí sería una Declaración SQL que se parezca a esto:
// final Request selection
SELECT request.[RequestId]
FROM [Request] request
// Only requests, which are successful, and have Max(date)
WHERE request.[RequestId] IN
(
SELECT successResponse.RequestId as y0_
FROM [Response] successResponse
// response which max date is equal to the upper response
// and which RequestId corresponds with supper upper Request
WHERE EXISTS
(
SELECT maxResponse.RequestId as y0_
, max(maxResponse.[DateTime]) as y1_
FROM [Response] maxResponse
// do the MAX only for current Request
WHERE maxResponse.RequestId = successResponse.RequestId
GROUP BY maxResponse.RequestId
// assure that the Response match is on the max DateTime
HAVING max(maxResponse.[DateTime]) = successResponse.[DateTime]
)
AND successResponse.[Success] = 1
)
Notas:
- Esperando la respuesta tiene
RequestId
- arriba se usó C #
//
comentario en lugar de SQL--
Y ahora la magia de NHibernate y QueryOver:
// This declaration will allow us, to use a reference from middle SELECT
// in the most deeper SELECT
Response response = null;
// the most INNER SELECT
var maxSubquery = QueryOver.Of<Response>()
.SelectList(l => l
.SelectGroup(item => item.RequestId)
.SelectMax(item => item.DateTime)
)
// WHERE Clause
.Where(item => item.RequestId == response.RequestId)
// HAVING Clause
.Where(Restrictions.EqProperty(
Projections.Max<Response>(item => item.DateTime),
Projections.Property(() => response.DateTime)
));
// the middle SELECT
var successSubquery = QueryOver.Of<Response>(() => response)
// to filter the Request
.Select(res => res.RequestId)
.WithSubquery
.WhereExists(maxSubquery)
// now only these wich are successful
.Where(success => success.Success == true)
;
En este momento, tenemos SUB SELECT internos, anidados. vamos a usarlos:
// the most outer SELECT
var query = session.QueryOver<Request>();
query.WithSubquery
// our Request ID is IN(...
.WhereProperty(r => r.ID)
.In(successSubquery);
var list = query
.List<Request>();
Notas finales, no estoy discutiendo el concepto. No el rendimiento. Usaría más bien un ajuste en la respuesta "IsActive" y lo haría más fácil ... esta es solo la respuesta de cómo hacerlo ...
Tengo un modelo de entidad como este:
public class Request
{
public virtual IList<Response> Responses { get; set; }
}
public class Response
{
public virtual DateTime Timestamp { get; set; }
public virtual bool Success { get; set; }
}
Estoy tratando de crear una consulta que me dará todas las solicitudes donde su última respuesta (con respecto a su marca de tiempo ) es correcta . ¿Cómo puede hacerse esto?
Voy a echar un vistazo a esto, aquí hay algo de linq (usando Query
lugar).
session.Query<Request>()
.Where(request =>
request.Responses.Count() > 0 &&
request.Responses.OrderByDescending(response => response.Timestamp)
.First()
.Success);
No tengo idea si esto funciona.