Entity framework 为树列表数据源组合来自不同对象类型的多个IQueryable
我寻找一种方法来组合来自不同对象类型的两个或多个iQueryable,以便将其用作树列表的数据源 对于树列表,我使用DevExpress WinForms组件“树列表”。 它为我提供了属性“KeyFieldName”,通常映射到“ID”和ParentFieldName,后者映射到父ID以构建层次结构 我使用实体框架6作为或映射器 我需要结合以下两个课程: XObject:Entity framework 为树列表数据源组合来自不同对象类型的多个IQueryable,entity-framework,devexpress,iqueryable,treelist,Entity Framework,Devexpress,Iqueryable,Treelist,我寻找一种方法来组合来自不同对象类型的两个或多个iQueryable,以便将其用作树列表的数据源 对于树列表,我使用DevExpress WinForms组件“树列表”。 它为我提供了属性“KeyFieldName”,通常映射到“ID”和ParentFieldName,后者映射到父ID以构建层次结构 我使用实体框架6作为或映射器 我需要结合以下两个课程: XObject: [Table("tbl_objects")] public class XObject { [C
[Table("tbl_objects")]
public class XObject
{
[Column("id")]
public int Id { get; set; }
[Column("display_name")]
public String DisplayName { get; set; }
[Column("description")]
public String Description { get; set; }
[Column("usage_reason")]
public String UsageReason { get; set; }
[Column("is_network_compatible")]
public bool IsNetworkCompatible { get; set; }
[Column("ip_address")]
public String IpAddress { get; set; }
[Column("network_name")]
public String NetworkName { get; set; }
[Column("serial_number")]
public String SerialNumber { get; set; }
[Column("manufacturer_identification_code")]
public String ManufacturerIdentificationCode { get; set; }
[Column("web_link")]
public String WebLink { get; set; }
[Column("warranty")]
public int WarrantyInDays { get; set; }
[Column("ref_manufacturer")]
public virtual XManufacturer Manufacturer { get; set; }
[Column("ref_order")]
public virtual XOrder Order { get; set; }
[Column("ref_owner")]
public virtual XOwner Owner { get; set; }
[Column("ref_room")]
public virtual XRoom Room { get; set; }
[Column("ref_object_folder")]
public virtual XObjectFolder ObjectFolder { get; set; }
public virtual ICollection<XAdditionalObjectData> AdditionalObjectData { get; set; }
}
[Table("tbl_object_folders")]
public class XObjectFolder
{
[Column("id")]
public int Id { get; set; }
[Column("display_name")]
public String DisplayName { get; set; }
[Column("short_name")]
public String ShortName { get; set; }
[Column("ref_parent_folder")]
public virtual XObjectFolder ParentFolder { get; set; }
public virtual ICollection<XObjectFolder> ChildFolders { get; set; }
public virtual ICollection<XObject> Objects { get; set; }
[NotMapped]
public int ParentFolderId { get { return ParentFolder == null ? -1 : ParentFolder.Id; } }
}
但是。。。谁会想到。。。出现了另一个问题:
查看数据库结构:
由于这两个对象存储在不同的表中,因此在组合它们时,id肯定不是唯一的。
这在设置数据源时是必需的。解决方案:
public enum ObjectTreeListElementTypes
{
Folder,
Object
}
[NotMapped]
public ObjectTreeListElementTypes TreeListElementType => ObjectTreeListElementTypes.Folder; // or *.Object for that matter
public class ObjectTreeListElementController
{
private List<ITreeListCombinable> _list;
public ObjectTreeListElementController()
{
_list = new List<ITreeListCombinable>();
}
public void AddRange(List<ITreeListCombinable> list)
{
// add incoming items to private _list
_list.AddRange(list);
}
public List<ITreeListCombinable> GetDataSourceList()
{
// create auto increment list id
var listId = 0;
foreach (var item in _list)
{
item.ListId = listId;
listId++;
}
// set new parent list id according to incremental list id
foreach (var item in _list)
{
var parents = _list.Where(x => x.Id == item.ParentId && x.TreeListElementType == ObjectTreeListElementTypes.Folder);
if (parents.Count() > 0)
item.ParentListId = parents.First().ListId;
else
item.ParentListId = -1;
}
return _list;
}
}
所以我采取了我自己的方法来解决我的问题,并且成功了
我认为自己是初学者,所以这个解决方案可能不是最好的。尽管如此,如果有人处于类似的情况,下面是它的工作原理:
首先,我创建了一个界面,文件夹和对象共享该界面:
ITreeListCombinable
public interface ITreeListCombinable
{
int Id { get; set; }
int ParentId { get; }
int ListId { get; set; }
int ParentListId { get; set; }
String DisplayName { get; set; }
ObjectTreeListElementTypes TreeListElementType { get; }
}
然后,我确保XObject和XObjectFolder类都保存了它们对应的ObjectTreeListerElementTypes值:
ObjectTreeListerElementTypes枚举:
public enum ObjectTreeListElementTypes
{
Folder,
Object
}
[NotMapped]
public ObjectTreeListElementTypes TreeListElementType => ObjectTreeListElementTypes.Folder; // or *.Object for that matter
public class ObjectTreeListElementController
{
private List<ITreeListCombinable> _list;
public ObjectTreeListElementController()
{
_list = new List<ITreeListCombinable>();
}
public void AddRange(List<ITreeListCombinable> list)
{
// add incoming items to private _list
_list.AddRange(list);
}
public List<ITreeListCombinable> GetDataSourceList()
{
// create auto increment list id
var listId = 0;
foreach (var item in _list)
{
item.ListId = listId;
listId++;
}
// set new parent list id according to incremental list id
foreach (var item in _list)
{
var parents = _list.Where(x => x.Id == item.ParentId && x.TreeListElementType == ObjectTreeListElementTypes.Folder);
if (parents.Count() > 0)
item.ParentListId = parents.First().ListId;
else
item.ParentListId = -1;
}
return _list;
}
}
课程:
public enum ObjectTreeListElementTypes
{
Folder,
Object
}
[NotMapped]
public ObjectTreeListElementTypes TreeListElementType => ObjectTreeListElementTypes.Folder; // or *.Object for that matter
public class ObjectTreeListElementController
{
private List<ITreeListCombinable> _list;
public ObjectTreeListElementController()
{
_list = new List<ITreeListCombinable>();
}
public void AddRange(List<ITreeListCombinable> list)
{
// add incoming items to private _list
_list.AddRange(list);
}
public List<ITreeListCombinable> GetDataSourceList()
{
// create auto increment list id
var listId = 0;
foreach (var item in _list)
{
item.ListId = listId;
listId++;
}
// set new parent list id according to incremental list id
foreach (var item in _list)
{
var parents = _list.Where(x => x.Id == item.ParentId && x.TreeListElementType == ObjectTreeListElementTypes.Folder);
if (parents.Count() > 0)
item.ParentListId = parents.First().ListId;
else
item.ParentListId = -1;
}
return _list;
}
}
因此,之后我编写了自己的“控制器”,用于处理我的特定场景
ObjectTreeListerElementController:
public enum ObjectTreeListElementTypes
{
Folder,
Object
}
[NotMapped]
public ObjectTreeListElementTypes TreeListElementType => ObjectTreeListElementTypes.Folder; // or *.Object for that matter
public class ObjectTreeListElementController
{
private List<ITreeListCombinable> _list;
public ObjectTreeListElementController()
{
_list = new List<ITreeListCombinable>();
}
public void AddRange(List<ITreeListCombinable> list)
{
// add incoming items to private _list
_list.AddRange(list);
}
public List<ITreeListCombinable> GetDataSourceList()
{
// create auto increment list id
var listId = 0;
foreach (var item in _list)
{
item.ListId = listId;
listId++;
}
// set new parent list id according to incremental list id
foreach (var item in _list)
{
var parents = _list.Where(x => x.Id == item.ParentId && x.TreeListElementType == ObjectTreeListElementTypes.Folder);
if (parents.Count() > 0)
item.ParentListId = parents.First().ListId;
else
item.ParentListId = -1;
}
return _list;
}
}
公共类ObjectTreeListerElementController
{
私人名单(private List);;
公共对象TreeListerElementController()
{
_列表=新列表();
}
公共无效添加范围(列表)
{
//将传入项目添加到专用\u列表
_list.AddRange(列表);
}
公共列表GetDataSourceList()
{
//创建自动递增列表id
var-listId=0;
foreach(列表中的var项)
{
item.ListId=ListId;
listId++;
}
//根据增量列表id设置新的父列表id
foreach(列表中的var项)
{
var parents=\u list.Where(x=>x.Id==item.ParentId&&x.TreeListElementType==ObjectTreeListElementTypes.Folder);
如果(parents.Count()>0)
item.ParentListId=parents.First().ListId;
其他的
item.ParentListId=-1;
}
返回列表;
}
}
本质上,当调用GetDataSourceList()方法时,它首先分发增量临时列表ID。
在第二个循环中,我搜索原始父id并匹配树列表元素类型。如果未找到,则此文件夹是我的树列表中的根文件夹,如果找到,则给定的列表id将成为父列表id:
using (var db = new XDbContext(_conString))
{
// Queryables
IQueryable<ITreeListCombinable> ofs = from of in db.ObjectFolders orderby of.DisplayName ascending select of;
IQueryable<ITreeListCombinable> objs = from obj in db.Objects orderby obj.DisplayName ascending select obj;
var lofs = ofs.ToList();
var lobjs = objs.ToList();
var ctrl = new ObjectTreeListElementController();
ctrl.AddRange(lofs);
ctrl.AddRange(lobjs);
var sourceList = ctrl.GetDataSourceList();
// As DataSource for my TreeList
TreeListObjects.DataSource = sourceList;
}
使用(var db=new XDbContext(_conString))
{
//牢骚
IQueryable ofs=db.ObjectFolders中的from of of orderby of.DisplayName升序选择of;
IQueryable objs=从数据库中的obj.Objects orderby obj.DisplayName升序选择obj;
var lofs=ofs.ToList();
var lobjs=objs.ToList();
var ctrl=新的ObjectTreeListerElementController();
ctrl.AddRange(lofs);
ctrl.AddRange(lobjs);
var sourceList=ctrl.GetDataSourceList();
//作为我的树列表的数据源
TreeListObjects.DataSource=sourceList;
}
这给我带来了我想要的精确输出:
希望这能帮助其他初学者:)