Я признаю, что большая часть моей проблемы с этим должна быть связана с простым непониманием вокруг нескольких компонентов, участвующих в решении. Я не совсем «новичок» в Entity Framework, кодовых и не общих типах, но внутренняя работа всех трех до сих пор достаточно таинственна для меня, что это дает мне возможность.Универсальный метод добавления в инфраструктуре сущностей - проблема с переходом типа из строкового имени
У меня есть код-первый проект, в котором я выделил классы «модели» из классов «обслуживания», с обобщениями в обоих. Я NOT с использованием всего Образцовый шаблон по разным причинам. Для большей части того, что я делаю, структура, которую я нахожу, прекрасно работает - я понимаю это, и это кажется совершенно чистым.
Но есть одна область, где я сталкиваюсь с проблемами, и это возможность передать один из моих типов классов модели в качестве общего параметра экземпляру общего объекта службы, учитывая строковый путь/имя модель класс.
(Фон: Мне нужно сделать это, потому что я «семя» нескольких таблиц в базе данных с значениями инициализации из файла JSON. Этот JSON-файл содержит имена модельных сущностей. Поэтому во время выполнения мне нужно . получить это значение строки, а затем кормить, что в качестве типа к родовому объекту сервиса, который делает операции базы данных)
Вот соответствующие фрагменты кода:
В BaseEntity.cs у меня есть верх -уровень интерфейса и ряд абстрактных классов, из которых затем наследуются конкретные объекты модели:
namespace POST.API.Models
{
public interface IEntity
{
int Id { get; set; }
}
public abstract class BaseEntity { }
public abstract class Entity : BaseEntity, IEntity
{
public virtual int Id { get; set; }
}
public abstract class TypeEntity : Entity
{
public TypeDefinition Definition { get; set; }
}
}
В BaseService.cs У меня есть другой интерфейс и более абстрактные классы, из которых специфические классы модели обслуживания унаследовать. Существует также один конкретный класс, вот, что обобщается для выполнения операции вставки:
namespace POST.API.Services
{
public interface IEntityService { }
public abstract class BaseEntityService<T> : IEntityService
where T : Models.BaseEntity
{
public T Fetch(int Id)
{
using (var Db = new PostDbContext())
{
return Db.Set<T>().Find(Id);
}
}
public void Create(T Item)
{
if (Item != null)
{
using (var Db = new PostDbContext())
{
DbSet Entity = Db.Set<T>();
Entity.Add(Item);
Db.SaveChanges();
}
}
}
public IEnumerable<T> All()
{
using (var Db = new PostDbContext())
{
return (IEnumerable<T>)Db.Set<T>().ToList();
}
}
}
public abstract class BaseTypeEntityService<T> : BaseEntityService<T>
where T : Models.TypeEntity
{ }
public abstract class BasePropertyTypeEntityService<T> : BaseTypeEntityService<T>
where T : Models.PropertyTypeEntity { }
public abstract class BasePropertyEntityService<T> : BaseEntityService<T>
where T : Models.BaseEntity { }
public class TypeEntityService<T> : BaseTypeEntityService<T>
where T : Models.TypeEntity { }
#endregion
}
Я удалил некоторые методы не подходящие для презентации.
У меня есть некоторый код, который затем пытается использовать эти базовые классы рыться файла JSON и вставить несколько строк, таким образом:
using (PostDbContext Db = new PostDbContext())
{
string JsonString = System.IO.File.ReadAllText(JsonDataFile);
DataSet JsonDataSet = JsonConvert.DeserializeObject<DataSet>(JsonString);
foreach (DataTable Table in JsonDataSet.Tables)
{
Type EType = Type.GetType("POST.API.Models." + Table.TableName);
POST.API.Models.BaseEntity E = (POST.API.Models.BaseEntity)Activator.CreateInstance(EType);
Services.TypeEntityService<EType> S = new Services.TypeEntityService<EType>();
foreach (DataRow Row in Table.Rows)
{
// Set properties of E and call Create method of S
}
}
}
Я явно неправильно понял что-то фундаментальное, потому что код не будет компиляции. На этой строке кода:
Services.TypeEntityService<EType> S = new Services.TypeEntityService<EType>();
... Я получаю ошибку на мои ссылки на ETYPE, с компилятором жалуясь «Тип или пространство имен` EType»не может быть найден.»
Таким образом, очевидно, что эта ссылка не может быть оценена во время выполнения. Который, таким образом, заставляет меня задаться вопросом, как я это делаю. Все связанные с этим темы, похоже, не дают удовлетворительного ответа - по крайней мере, не в том смысле, который имеет смысл в контексте моей собственной реализации.
Хорошо. Это имеет смысл для меня в некоторых отношениях и действительно решает одну проблему. Однако я все еще не могу ссылаться на свойства и методы переменных E и S, что является целым ... То есть я не могу фактически установить свойства E, а затем вызвать метод Create для S, чтобы добавить новый E ... –
Я не включил код для создания E, но оттуда вам нужно будет использовать отражение для вызова метода из 'var method = S.GetMethod (« MyMethodName »);' и затем 'var result = method .Invoke (generic, new object [] {E}); ' –
За исключением того, что S не имеет доступного метода GetMethod, по крайней мере, так, как код присутствует в структуре ... S имеет только равные, GetType, GetHashCode и ToString , как var ... –