Значение «CitiesDomain.Cities» не относится к типу «CitiesDomain.Cities» и не может использоваться в этой универсальной коллекции. Имя параметра: значение - PullRequest
0 голосов
/ 14 августа 2011

Мне нужна помощь с сообщением об ошибке, которое я получаю. По сути, я занимаюсь разработкой библиотеки классов динамической отчетности с использованием C # .NET и NHibernate.

Сам отчет будет реализован через класс с использованием пользовательских атрибутов для указания метаданных и любых требуемых параметров, включая любые таблицы поиска, которые могут ему понадобиться, например:

[Report( Guid="{D9DEB982-02A3-4700-868D-404E615F1DDA}", 
 Title="Golf Course Report", 
 Description= "Produces a list of golf courses by city" )]
[LookupParameter( ParamName="City", LookupTable="Cities", LabelName="Select a city" )]
[LookupTable( Table="Cities", IDColumn="CityID", ValueColumn="CityName" )]
public class GolfCourseReportByCity : Report { }

Когда веб-приложение запускается, оно перечисляет все сборки в папке \bin и загружает их одним, ища классы, которые были украшены атрибутом Report. Когда он встречает атрибут LookupTable, он генерирует новую сборку, используя Reflection Emit, чтобы создать класс со свойствами, заданными параметрами атрибута IDColumn и ValueColumn. Кроме того, файл сопоставления NHibernate .hbm.xml будет сгенерирован динамически и встроен в сборку, так что NHibernate сам загрузит его в свою конфигурацию.

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

Type generic = typeof( GolfScoreDAL.PersistenceManager<> );
Type constructed = generic.MakeGenericType( EntityType );
dynamic instance = Activator.CreateInstance( constructed );
dynamic results = instance.FindAll();

Этот блок кода создает общий экземпляр DAL

PersistenceManager<CitiesDomain.Cities>

Универсальный параметр CitiesDomain.Cities берется из свойства EntityType, которое задается в процессе перечисления сборки и содержит Type самого класса домена. К сожалению, при вызове строки instance.FindAll() выше я получаю следующее сообщение об ошибке:

The value "CitiesDomain.Cities" is not of type "CitiesDomain.Cities" and cannot be used in this generic collection. Parameter name: value

Эта ошибка выдается в строке return results.List<T>(); в коде ниже:

    public IList<T> FindAll()
    {
        using ( ISession session = OpenSession() )
        {
            var results = session.CreateCriteria( typeof( T ) );
            return results.List<T>(); // <------ falls over here
        }
    }

Я не понимаю, почему, поскольку универсальный тип T совпадает с типом результатов, возвращаемых методом CreateCriteria, то есть ввод следующего в промежуточном окне подтверждает это.

? results.List()[0] is typeof(T)
true

По какой-то причине return results.List<T>(); не работает, но return results.List(); работает.

Если я заменил строку Type constructed = generic.MakeGenericType( EntityType ); выше на конкретный класс домена, на который ссылается проект, он работает и не выдает ошибку, например, Type constructed = generic.MakeGenericType( typeof(City) );

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

Может кто-нибудь сказать мне, почему код не работает, иначе дни работы будут утеряны в канализацию и обратно на чертежную доску.

Заранее спасибо.

1 Ответ

0 голосов
/ 15 августа 2011

Является ли EntityType статическим типом или сгенерированным временем выполнения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...