В настоящее время у меня есть база данных иерархии отношений «один ко многим» tblProjects-> tblLines-> tblGroups-> tblStations и т. д. И модель Entity framework 6.
Все эти классы структуры сущностей реализуют базовый класс tblBase:
public abstract class TblBase : INotifyPropertyChanged
{
private int _id;
public int ID
{
get
{
return _id;
}
set
{
_id = value;
NotifyPropertyChanged();
}
}
private Nullable<int> _coid;
public Nullable<int> COID
{
get
{
NotifyPropertyChanged();
return _coid;
}
set
{
_coid = value;
NotifyPropertyChanged();
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
NotifyPropertyChanged();
}
}
У меня есть древовидное представление, которое позволяет мне выбрать любой узел в качестве родительского типа, и в настоящее время у меня есть метод для каждого типа, который позволяет мне перезагружать все дочерние объекты.
Я хотел бы увидеть, как это можно сделать универсальным:
private async static Task<bool> RefreshLinesAsync(LocalUser ThisUser, ProjectEntities DBContext, object Entity)
{
List<object> NonExistingNodes = new List<object>();
var bContinue = false;
var PassedEntity = Entity as TblBase;
//Scan through all DB child entities and reload their DB values
foreach (var SubEntity in DBContext.tblLines.Where(x => x.ProjectID == PassedEntity.ID).ToList())
{
await DBContext.Entry(SubEntity).ReloadAsync().ContinueWith(x =>
{
if (!x.IsFaulted)
{
if ((SubEntity.COID.GetValueOrDefault() != 0) && (SubEntity.COID.GetValueOrDefault() != ThisUser.ID))
NotifyCOIDConflict(SubEntity, new CheckedOutArgs()
{
ConflictCOID = SubEntity.COID.GetValueOrDefault()
});
bContinue = true;
}
}, TaskScheduler.FromCurrentSynchronizationContext());
if (bContinue)
//Continue to child entities method
await RefreshGroupsAsync(ThisUser, DBContext, SubEntity);
}
return true;
}
private async static Task<bool> RefreshGroupsAsync(LocalUser ThisUser, ProjectEntities DBContext, object Entity)
{
List<object> NonExistingNodes = new List<object>();
var bContinue = false;
var PassedEntity = Entity as TblBase;
foreach (var SubEntity in DBContext.tblGroups.Where(x => x.LineID == PassedEntity.ID).ToList())
{
await DBContext.Entry(SubEntity).ReloadAsync().ContinueWith(x =>
{
if (!x.IsFaulted)
{
if ((SubEntity.COID.GetValueOrDefault() != 0) && (SubEntity.COID.GetValueOrDefault() != ThisUser.ID))
NotifyCOIDConflict(SubEntity, new CheckedOutArgs()
{
ConflictCOID = SubEntity.COID.GetValueOrDefault()
});
bContinue = true;
}
}, TaskScheduler.FromCurrentSynchronizationContext());
if (bContinue)
await RefreshStationsAsync(ThisUser,DBContext, SubEntity);
}
return true;
}
Единственный метод, который я считаю полезным, - это Set (), хотя он не предоставляет метод Where (), что очень важно, поскольку я не хочу получать всю таблицу.
@Seididieci Я пробовал это, у меня есть исключение, что моя tblBase не является частью моей модели
Извините, я не заметил, что ваш базовый класс абстрактный ... Как насчет того, чтобы сделать вашу функцию универсальной как private async static Task<bool> RefreshLinesAsync<TEntity>(LocalUser ThisUser, ProjectEntities DBContext, TEntity Entity)?
@Seididieci Я мог бы попробовать это, не могли бы вы примерно показать мне, как этот метод будет выглядеть?





Вы можете сделать свои функции универсальными. Возможно, им понравится этот:
private async static Task<bool> RefreshLinesAsync<TEntity>(LocalUser ThisUser, ProjectEntities DBContext, TEntity Entity) where TEntity : TblBase
{
List<TEntity> NonExistingNodes = new List<TEntity>();
var bContinue = false;
var PassedEntity = Entity as TblBase;
foreach (var SubEntity in DBContext.Set<TEntity>().Where(x => (x as TblBase).ProjectID == PassedEntity.ID).ToList()) {
//Your other code here...
}
}
Предложение where в определении функции, убедитесь, что этот метод можно вызывать только с подклассами TblBase.
Обновлено:
Я забыл упомянуть, что вам нужно преобразовать SubEntity как TblBase внутри цикла foreach, чтобы использовать его ...
РЕДАКТИРОВАТЬ (в ответ на комментарии):
Если вам нужно получить все подклассы TblBase от вашей сущности, вы не сможете сделать свою функцию такой универсальной, если будете хранить их в отдельных таблицах: это станет труднодоступным, когда вам нужно будет добавить больше подклассов.
Я предлагаю вам использовать одну таблицу через Table Per Hierarchy (см. Статью это в MSDN), изменяя TblBase с абстрактного на конкретный класс, тогда вы можете получить их все следующим образом:
var allSubClassEntities = DBContext.Set<TblBase>();
Я реализовал это, но теперь проблема в том, что моя SubEntity имеет тот же тип, что и моя Entity, и мне нужно, чтобы она принимала тип дочерних сущностей.
Кроме того, выражения позволяют мне получить доступ только к свойствам tblBase. ProjectID - это свойство навигации моих таблиц tblLines. Мне нужно как-то указать свойство навигации.
В dbcontext есть метод Set <TEntity> (), который имеет функцию Where (). Вы можете использовать его со своим базовым типом:
DBContext.Set<TblBase>().Where(...).