c# - ConfiguraciónElementoColección y Linq
custom-configuration (3)
He escrito algunas colecciones de configuración personalizadas, elementos, etc. Ahora, me gustaría hacer una declaración Linq simple:
ServerDetails servers = ConfigurationManager.GetSection("serverDetails") as ServerDetails;
var server = from s in servers
where s.Name == serverName
select s;
Me sale el error
No se pudo encontrar una implementación del patrón de consulta para el tipo de origen ''MyNamespace.ServerDetails''. ''Donde'' no encontrado.
El ServerElement
tiene dos propiedades:
public class ServerElement : ConfigurationElement
{
[ConfigurationProperty("ip")]
public string IP
{
get { return (string)base["ip"]; }
set { base["ip"] = value; }
}
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
get { return (string)base["name"]; }
set { base["name"] = value; }
}
}
ServerDetails
public sealed class ServerDetails : ConfigurationSection
{
[ConfigurationProperty("ServerCollection")]
[ConfigurationCollection(typeof(ServerCollection), AddItemName = "add")]
public ServerCollection ServerCollection
{
get { return this["ServerCollection"] as ServerCollection; }
}
}
ServerCollection
public sealed class ServerCollection : ConfigurationElementCollection
{
public void Add(ServerElement ServerElement)
{
this.BaseAdd(ServerElement);
}
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
}
protected override ConfigurationElement CreateNewElement()
{
return new ServerElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServerElement)element).Name;
}
}
¿Me estoy perdiendo de algo? ¿Necesito agregar algo para poder usar Linq con un elemento de configuración personalizado?
Por cierto, he estado using System.Linq;
definido como lo estoy usando en otro lugar dentro de la misma clase.
Al usar el ejemplo simple de Brian Gideon de rendimiento en su implementación de IEnumerable <T>, pude enumerar sobre mi ConfigurationElementCollection.
Se vería algo así (usando la pregunta original):
public sealed class ServerCollection : ConfigurationElementCollection,
IEnumerable<ServerElement>
{
...
public new IEnumerator<ServerElement> GetEnumerator()
{
foreach (var key in this.BaseGetAllKeys())
{
yield return (ServerElement)BaseGet(key);
}
}
}
Mientras no estaba recibiendo el error:
No se pudo encontrar una implementación del patrón de consulta para el tipo de origen ''MyNamespace.ServerDetails''. ''Donde'' no encontrado
... Tampoco pude iterar sobre mi ConfigurationElementCollection usando LINQ. Esta solución solucionó mi problema para que pudiera usar LINQ para iterar sobre mi colección.
De acuerdo, dado que todo está escrito de manera débil, deberá llamar a Cast<>
o OfType<>
explícitamente, o dar un tipo explícito a la variable de rango. También deberá especificar la propiedad ServerCollection
en sus ServerDetails
. Por ejemplo:
ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
where s.Name == serverName
select s;
var server = ((ServerDetails) ConfigurationManager.GetSection("serverDetails")).
ServerCollection.Cast<ServerElement>().FirstOrDefault(x => x.Name == serverName);