Могу ли я начать со строки и создать экземпляр объекта этой строки? - PullRequest
3 голосов
/ 11 января 2009

Я сейчас работаю с LINQ и C #.

У меня есть DropDownList таблиц в моей модели LINQ to SQL.

Я хочу, чтобы пользователь мог выбрать имя таблицы LINQ из DropDown. В коде я хочу создать экземпляр этого класса LINQ, а затем запустить Select, или его, или все, что я хочу.

Как мне выполнить создание объекта, основываясь на том, какое имя объекта в строке выбрал пользователь? Я неправильно думаю с самого начала?

Ответы [ 5 ]

6 голосов
/ 11 января 2009

Вы хотите Type.GetType (строка) и Activator.CreateInstance (Тип) .

Обратите внимание, что Type.GetType (string) будет искать только текущую сборку и mscorlib, если вы не укажете полное имя типа, включая сборку. В любом случае вам нужно указать имя типа, включая пространство имен.

Другой альтернативой является использование Assembly.GetType (string) для получения типа непосредственно из строки перед вызовом Activator.CreateInstance.

(На самом деле здесь есть много альтернатив. Если вам не поможет ни одна из них, пожалуйста, опишите больше информации, и я уверен, что мы сможем найти способ пойти дальше.)

3 голосов
/ 11 января 2009

Поскольку вы пометили сообщение с помощью ASP.NET, я предполагаю, что этот список находится на стороне клиента. Если это так, вы должны быть очень осторожны, доверяя этим данным, и я бы не рекомендовал создавать типы непосредственно из пользовательского ввода. Вы можете использовать данные в качестве входных данных для фабрики, которая затем может вернуть правильный экземпляр (и обработать любой неправильный ввод по своему усмотрению).

1 голос
/ 11 января 2009

Разработка предупреждения Брайана Расмуссена: типы должны быть ограничены и требуют осознанного замысла. Желательно, чтобы «пользовательские» типы были помечены специальным пользовательским атрибутом, который можно проверить с помощью отражения.

1 голос
/ 11 января 2009

В LINQ-to-SQL есть определенные способы сделать это из контекста данных; в основном db.GetTable. Это возвращает ITable, но работать с нетипизированным ITable немного сложно. Вы можете перечислить это, по крайней мере ...

Чтобы получить ITable, вам обычно требуется Type, который вы можете получить (например) Assembly.GetType:

    using (var ctx = new MyDataContext()) {
        string name = "Customer"; // type name
        Type ctxType = ctx.GetType();
        Type type = ctxType.Assembly.GetType(
            ctxType.Namespace + "." + name);
        ITable table = ctx.GetTable(type);
        foreach(var row in table) {
            Console.WriteLine(row); // works best if ToString overridden...
        }
    }

Конечно, когда у вас есть Type, вы используете Activator для создания новых экземпляров сущности:

        object newObj = Activator.CreateInstance(type);
        // TODO: set properties (with reflection?)
        table.InsertOnSubmit(newObj);

но если вы хотите использовать имя свойства, это тоже может сработать:

    using (var ctx = new MyDataContext()) {
        string name = "Customers"; // property name
        ITable table = (ITable) ctx.GetType()
            .GetProperty(name).GetValue(ctx, null);
        foreach (var row in table) {
            Console.WriteLine(row); // works best if ToString overridden...
        }
    }

Запустить фильтры (Where) и т. Д. Сложно с нетипизированными данными, поскольку сборка Expression была бы сложной. Я бы, вероятно, начал переключаться на типизированную модель в этот момент ...

0 голосов
/ 16 июля 2009

Следить за ответом Марка Гравелла.

Делая, как он предложил, я заметил Cast<TResult> метод расширения (определенный в System.Linq).

К сожалению, вы не можете использовать экземпляр type для приведения:

Type dcType = dc.GetType();
Type type = dcType.Assembly.GetType(String.Format("{0}.{1}", dcType.Namespace, name));
var row = dc.GetTable(type).Cast<type>().SingleOrDefault(i => i.ID == 123);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...