Version Info:DbSet.Cast <TEntity>() Ошибка: Не удается создать DbSet <IEntity> из необщего DbSet для объектов типа 'организации'
Я использую C# 4.5, Entity Framework 6.0, и MEF ,
Код и блок испытаний
Я создал проект испытания, чтобы объяснить эту проблему: https://skydrive.live.com/redir?resid=E3C97EC293A34048!2234
Пожалуйста, откройте проект UnitTest и попытаться запустить TestIfItWorks модульного тестирования().
Проблема
Я хочу, чтобы преобразовать необщего DbSet его дженерика, но я получаю следующее исключение: InvalidCastException: Cannot create a DbSet<IUser> from a non-generic DbSet for objects of type 'User'
:
var nonGeneric = context.Set(typeof(User));
var generic = nonGeneric.Cast<IUser>(); //Exception in here
Класс Пользователь реализующий IUser так что вы бы подумайте, что приведение не должно быть проблемой, если только код DbSet не ограничен конкретными классами (я надеюсь, что в противном случае мне не нужно создавать оболочку вокруг не-общего DbSet, чтобы преобразовать его в общий DbSet или найти альтернативу текущей реализации DbSet) ,
Если вам интересно, почему я использую интерфейсы, даже если они в настоящее время не поддерживаются Microsoft, я даю вам небольшое объяснение (надеюсь, это отфильтровало бы ответы, которые говорят «Do not Do That» вместо предоставления решения) :
Я использую MEF и EntityFramework для создания слабо связанного механизма уровня данных, через который я могу предоставить Entities (и их соответствующие конфигурации) для каждого проекта. Я очень интенсивно использую интерфейсы для определения движка. Метаданные и конкретная реализация объектов в контексте обнаруживаются во время выполнения с использованием MEF.
Отрывок из кода
[TestMethod]
public void TestIfItWorks()
{
//TODO: Please open the App.Config and change the PluginsPath to match the Plugins folder in your machine.
using (var dbContext = new MyContext()) //Please ignore this line for now. This was UnitOfWork which I replaced with Context to create a simple unit test
{
dbContext.Setup(); //Please ignore this line for now. This was part of UnitOfWork which I moved to here to create a simple unit test
//The purpose of all these is to be able to read and write user info from/to database while User class is defined in an external assembly
//but we can import it by MEF using IUser interface.
//Failed Attempt# 1: Use User class directly! This doesnt work because User is in an external class which we dont have reference to
//var failedAttempt1 = dbContext.Set<User>();
//Failed Attempt# 2: But the good thing is that we have access to IUser and its exports
//then lets get a DbSet<IUser> instead
var failedAttempt2 = dbContext.Set<IUser>();
try
{
var throwsException2 = failedAttempt2.FirstOrDefault();
}
catch (InvalidOperationException ex)
{
//InvalidOperationException:
// The entity type IUser is not part of the model for the current context.
// It also didnt work when I tried to define a class that inherits from EntityTypeConfiguration<IUser>at TestImplementation
}
//Ok then lets do it differently this time. Lets get User type (that we know we have good configuration for)
//from our Container and ask Context to give us the nonGeneric version
var userImplementationType = Logic.Instance.GetExportedTypes<IUser>().FirstOrDefault();
Assert.IsNotNull(userImplementationType, "We havn't been able to load TestImplementation into catalog. Please ensure the PluginsPath is set correctly at App.Config");
var nonGeneric = dbContext.Set(userImplementationType);
//
// This is working so far, we can add and remove records from database using
// the nonGeneric version of DbSet. You can uncomment the following code block provide a unique ID
// and test it yourself.
//
var newUser = Logic.Instance.New<IUser>();
newUser.Id = "99";
newUser.UserName = "Aidin Sadighi";
nonGeneric.Add(newUser);
try
{
dbContext.SaveChanges();
}
catch (DbUpdateException ex)
{
//This is OK because most probably this is a duplicate user. Just increase the Id to make it unique.
}
//Failed Attempt#3: Cast non generic DbSet to generic
try
{
//TODO: I need to fix this. Help me please
var genericSet = nonGeneric.Cast<IUser>();
}
catch (InvalidCastException ex)
{
//Cannot create a DbSet<IUser> from a non-generic DbSet for objects of type 'User'.
throw;
}
}
}
Как о 'IQueryable родовое = nonGeneric.Cast ();'? –
haim770
Я знаю jack о Entity Framework, но, глядя на код, я довольно скептически отношусь к context.Set(). эта работа: Пользователь nonGeneric = context.Set (typeof (Пользователь)); ..если нет, то его нормальное, что приведение тоже не является, и если это так, просто используйте IUser generic = context.Set (typeof (User)); – Robert
Спасибо за ответ, но это не работает для меня. Я редактировал свой вопрос, чтобы предоставить пример кода и более подробную информацию. Спасибо – Aidin