user771184
user771184

Reputation: 33

Generics and LINQ to XML

I am having a go at creating a generic xmlRepository where I can pass in any type and get a list back.

At the moment my code looks like this (Only way I can get it to work):

public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
    var filename = GetEntityFileName<TEntity>();
    var doc = XDocument.Load(filename);
    var query = (from p in doc.Descendants(entityName)
                 select (ServiceAccount)p).AsQueryable().Cast<TEntity>();
    return query;
}

I would like to swap out the

select (ServiceAccount)p).AsQueryable().Cast<TEntity>();

with

select (TEntity)p).AsQueryable();

TEntity is the same object as ServiceAccount,

Is this possible with LINQ to XML?

I have a SQLRepository, using EF, which has the same method in it and I am looking for the LINQ to XML equivalent of

((IObjectContextAdapter)_context).ObjectContext.CreateQuery<TEntity>(entityName);

If indeed there is one.

Upvotes: 3

Views: 1185

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1502756

You need to specify how you're going to convert an XElement to an instance of T. Currently your code simply won't work unless ServiceAccount already has an explicit conversion from XElement.

You may want to have a convention of having a static FromXElement method in each entity type - you could then invoke that from reflection, or even have a dictionary:

private static readonly Dictionary<Type, Delegate> Converters =
    new Dictionary<Type, Delegate> {
        { typeof(ServiceAccount),
          (Func<XElement, ServiceAccount>) ServiceAccount.FromXElement },
        { typeof(OtherEntity),
          (Func<XElement, OtherEntity>) OtherEntity.FromXElement },
    };

You'd then write something like:

public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
    Delegate converter;
    if (!Converters.TryGetValue(typeof(TEntity), out converter))
    {
        throw new InvalidOperationException("...");
    }
    Func<XElement, TEntity> realConverter = (Func<XElement, TEntity>) converter;

    var filename = GetEntityFileName<TEntity>();
    var doc = XDocument.Load(filename);
    return doc.Descendants(entityName)
              .Select(realConverter)
              .AsQueryable();
}

It's not really clear why you're using IQueryable<T> here, by the way... anything wrong with just IEnumerable<T>?

Upvotes: 3

abatishchev
abatishchev

Reputation: 100328

p isXElement, right?

Then you cast ServiceAccount on it. Does it work?

What is signature of this class?

I doubt whether generic constraint TEntity : class will work.

Upvotes: 0

Related Questions