Обобщения и LINQ to XML - PullRequest
3 голосов
/ 26 мая 2011

Я пытаюсь создать общий xmlRepository, в котором я могу передать любой тип и получить список обратно.

В данный момент мой код выглядит следующим образом (только так я могу заставить его работать):

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;
}

Я бы хотел поменять

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

на

select (TEntity)p).AsQueryable();

TEntity - это тот же объект, что и ServiceAccount,

Возможно ли это с помощью LINQ to XML?

У меня есть SQLRepository, использующий EF, в котором используется тот же метод, и я ищу LINQ to XML, эквивалентный

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

Еслидействительно, есть один.

Ответы [ 2 ]

3 голосов
/ 26 мая 2011

Вам нужно указать, как вы собираетесь конвертировать XElement в экземпляр T.В настоящее время ваш код просто не будет работать, если ServiceAccount уже не имеет явного преобразования из XElement.

Возможно, вы захотите иметь соглашение о наличии статического метода FromXElement в каждом типе сущности - вы можетезатем вызовите это из отражения или даже получите словарь:

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 },
    };

Затем вы напишите что-то вроде:

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();
}

Не совсем понятно, почему вы используете IQueryable<T>здесь, кстати ... что-то не так с просто IEnumerable<T>?

0 голосов
/ 26 мая 2011

p равно XElement, верно?

Тогда вы наложите на него ServiceAccount.Работает ли это?

Что такое подпись этого класса?

Сомневаюсь, будет ли работать общее ограничение TEntity : class.

...