Я столкнулся с этой проблемой в нашем проекте, где у нас есть ядро DBContext
и несколько «подключаемых» модулей со своими собственными DBContexts
, в которых «пользователь модуля» наследует «основного (базового) пользователя».Надеюсь, это понятно.
Нам также потребовалась возможность изменить (давайте назовем это) User
на Customer
(и при необходимости также на другое "унаследованное" Users
в то же время, чтобы этот пользовательможно использовать все эти модули.
Из-за этого мы попытались использовать наследование TPT вместо TPH - но TPH тоже бы сработал.
Один из способов - использовать пользовательскую хранимую процедуру как подсказывают многие ...
Другой способ, который мне пришёл в голову, - это отправить пользовательский запрос на вставку / обновление в БД. В TPT это будетbe:
private static bool UserToCustomer(User u, Customer c)
{
try
{
string sqlcommand = "INSERT INTO [dbo].[Customers] ([Id], [Email]) VALUES (" + u.Id + ", '" + c.Email + "')";
var sqlconn = new SqlConnection(ConfigurationManager.ConnectionStrings["DBContext"].ConnectionString);
sqlconn.Open();
var sql = new SqlCommand(sqlcommand, sqlconn);
var rows = sql.ExecuteNonQuery();
sqlconn.Close();
return rows == 1;
}
catch (Exception)
{
return false;
}
}
В этом сценарии Customer
наследует User
и имеет только string Email
.
При использовании TPH запрос будет изменяться только с *От 1030 * до UPDATE ... SET ... WHERE [Id] = ...
. Не забудьте также изменить столбец Discriminator
.
После следующего вызова dbcontext.Users.OfType<Customer>
наш первоначальный пользователь "преобразован" в клиента.
Итог: я также попробовал решение другого вопроса, который включал отсоединение оригиналty (пользователь) из ObjectStateManager
и создание нового состояния сущности (клиента) , изменение , сохранение dbcontext.SaveChanges()
.Это не сработало для меня (ни TPH, ни TPT).Либо потому, что для каждого модуля используются отдельные DBContexts, либо EntityFramework 6 (.1) игнорирует это. Его можно найти здесь.