dernière fois que je posté (la semaine dernière), je ne l'ai pas décrit correctement le problème. J'ai créé un échantillon rapide de ce problème. L'interrogation des collections locales fonctionne correctement lorsque vous l'utilisez dans le cadre de la requête de base. Le problème que je trouve est de l'utiliser avec une partie d'une sous-requête. Par exemple.
Ceci est assez difficile à décrire sans vous donner un schéma de base de données ou un schéma de code, mais je ferai de mon mieux. J'essaye d'exécuter mon code avec une requête à la DB. Je ne veux pas avoir à le décomposer et envoyer plusieurs commandes. Le faire de cette façon a certains avantages, y compris un éviter un problème possible que je vais expliquer vers la fin de cela.
Je rejoins certaines tables qui ont une relation. La table attributs (DataEventAttributes) décrit bien sûr les attributs propres à une ligne spécifique de la table principale (DataEvents).
Lorsque je l'interroge sans aucune collecte locale, chose fonctionne très bien et extrêmement rapidement contre ma base de données de 20 Go. Cependant, si je jette une collection locale de valeurs dans une partie de la sous-requête qui obtient les résultats, j'obtiendrai les "Requêtes avec des collections locales non supportées"
Cela a été assez difficile à reproduire dans mon code, donc je vais le commenter aussi bien que je peux faire, vous pouvez suivre ce que je fais.
// gets the initial query and join. We actually only care about the ID in the end, but we use the joined data
// to determine if a row needs to be pulled.
var initialQuery = from dataEvent in DataEvent.GetByQueryExpression(context)
join attribute in DataEventAttribute.GetByQueryExpression(context) on dataEvent.DataEventID
equals attribute.DataEventID
select new
{
ID = dataEvent.DataEventID,
PluginID = dataEvent.DataOwnerID,
TimeStamp = dataEvent.DataTimeStamp,
DataEventKeyID = attribute.DataEventKeyID,
ValueString = attribute.ValueString,
ValueDecimal = attribute.ValueDecimal
};
// list of some ids that we need to confirm exist in the initial query before the final query
var someSetOfIDs = new List<int>() {1, 2, 3, 4, 5};
// This is the local collection thats filtering out some results before I rebuild the entire result set in the final query
// If you comment this line out, the finalQuery will execute just fine.
// with this in place, the "Queries with local collections are not supported" error will come about.
initialQuery = initialQuery.Where(x => x.DataEventKeyID == 1 && someSetOfIDs.Contains((int) x.ValueDecimal));
// reusable query for the sub queries in the results -- not part of the problem, just part of the example
var attributeBaseQuery = from attribute in DataEventAttribute.GetByQueryExpression(context) select attribute;
// Builds the final result With the IDs from the initial query
// the group by is to remove any duplicates that may be in the collection.
// the select key is getting the ID that i needed
// the select ID is the ID of the first item that was grouped.
// the contains compares the local dataEvent object with the ID table (checking to see if it exists)
// the result is just an example of one item I can be pulling out of the database with the new type
var finalQuery = from dataEvent in DataEvent.GetByQueryExpression(context)
where initialQuery.GroupBy(x => x).Select(x => x.Key).Select(x => x.ID).Contains(dataEvent.DataEventID)
select new
{
BasicData =
attributeBaseQuery.Where(
attrValue =>
attrValue.DataEventID == dataEvent.DataEventID &&
attrValue.DataEventKeyID == (short) DataEventTypesEnum.BasicData).FirstOrDefault().
ValueString
};
var finalResult = finalQuery.Take(100).ToList();
L'une solution j'ai trouvé est de faire un .ToList() après la .Select (x => x.ID) dans le finalQuery, mais l'effet secondaire comporte deux négatifs. Premièrement, il exécute cette requête en premier, et obtient les ID de la base de données. Ensuite, il doit renvoyer ces résultats au serveur SQL en tant que paramètres de la requête finale. Le second problème majeur (show stopper) est que s'il y a beaucoup de résultats dans le .ToList(), le serveur SQL lancera un étrange message d'erreur et les recherches Google montrent qu'il y a beaucoup de paramètres passés (ce qui aurait du sens, le nombre de paramètre pourrait être dans les 10-100s de milliers). Donc, cela dit, j'essaie de comprendre comment construire une requête que je peux ajuster les critères dynamiquement, puis reconstruire mes ensembles de résultats avec tous les attributs qui correspondent à l'ID qui répond aux critères de la sous-requête . Dans le serveur SQL via le studio, cela fonctionne très bien, mais le problème de la collection m'a un hold-up. J'ai essayé de plusieurs façons, mais il semble que la seule façon de reproduire cela est d'avoir une requête qui utilise une collection locale, puis d'utiliser cette requête dans le cadre d'une autre requête qui filtre les résultats en utilisant la première requête.
Des idées comment je peux le faire?
Screen shot show you know I'm not crazy.
Merci à l'avance pour l'aide
Dahlbyk, Merci beaucoup. L'option 2 était le chemin à parcourir. Le SQl résultant était: OERE (([t5]. [ValeurDécimale] = @ p1) OU ([t5]. [ValeurDécimale] = @ p2) OU ([t5]. [ValeurDécimale] = @ p3) OU ([ t5]. [ValueDecimal] = @ p4) OU ([t5]. [ValueDecimal] = @ p5)) ET ([t5]. [DataEventKeyID] = @ p6) C'était exactement ce que je voulais/je voulais. Ce que vous avez montré dans votre exemple a prolongé mon processus de pensée et peut avoir résolu d'autres idées dans ma tête. Merci beaucoup pour la solution! – TravisWhidden