显示数据库的所有内容 - 显示 EDM 模型中所有实体的所有行
Showing all Content of a database - Show all rows of all entities in EDM model
在我的 EF6 应用程序上,我想显示当前在我的数据库中的所有实体的所有行。有没有一种方法可以做到这一点而不必知道我的实体是什么以及这些实体的属性是什么?我认为使用反射是解决这个问题的方法,但我无法找到解决方案。有什么想法吗?
更新:回复人们的问题...
数据库是SQLSERVER。
我不明白我想在这里具体实现的目标有何相关性。它甚至可以用于编写例程以查看所有数据的练习。
至于安全原因,例如,如果我想通过应用程序管理安全性或授予某人管理员权限以随心所欲地管理数据库,我不明白为什么这是一个设计问题。
看到所有已发布的链接,但到目前为止所有这些链接,解决方案包括构建 sql 语句,这是我想要摆脱的。
所以作为一个简单的例子并总结我的求助,我想要的是通过 c#,使用 Entity framework 和 Linq,能够编写一个执行 "show me everything" 命令的方法茉莉花谈起。
可能是因为我决定不喜欢字母 "a" 并想从数据库中清除它。
可能是因为我想查找所有包含单词 "fido" 的记录
一些地方。
可能是因为我想知道我的数据库有多少 words/numbers。
像这样,我想要这样做的原因还有很多,尽管就像我说的那样我觉得它无关紧要。
唯一的方法是获取 DbContext
中定义的所有实体,获取每个实体的 Set
,然后序列化实体(您没有指定格式) 并将其写入文件或您想要存储结果的任何位置。
public void GetDbSets(DbContext ctx)
{
// Initialize, to build the metadata
ctx.Database.Initialize(true);
// Access the underlying ObjectContext
var objectContext = ((IObjectContextAdapter)ctx).ObjectContext;
// Get the metadata for the DbContext
MetadataWorkspace mdw = objectContext.MetadataWorkspace;
// get the assembly, where the entity types are defined
var asm = ctx.GetType().Assembly;
// Get the metadata for the entity types
ReadOnlyCollection<EntityType> entityTypes
= mdw.GetItems<EntityType>(DataSpace.CSpace);
foreach (var et in entityTypes)
{
var type = asm.GetType(et.FullName);
Console.WriteLine("{0}: {1}", et.FullName,
string.Join(", ", et.Members.Select(m => m.Name).ToArray()));
var dbEntries = ctx.Set(type).AsNoTracking().AsQueryable();
foreach (var e in dbEntries)
{
var propValues = et.Members
.Select(m => type.GetProperty(m.Name).GetValue(e).ToString())
.ToArray();
Console.WriteLine(" {0}", string.Join(", ", propValues));
}
}
}
注意:代码未优化。每当你使用反射时,你应该缓存 PropertyInfo
s 以重用它们,而不是一遍又一遍地获取它们。此代码有效,但未优化。例如,对于内部循环,您可以这样做:
var propInfos = new Dictionary<string, PropertyInfo>();
et.Members.ForEach(m => propInfos.Add(m.Name, type.GetProperty(m.Name)));
foreach (var e in dbEntries)
{
var propValues = et.Members
.Select(m => propInfos[m.Name].GetValue(e).ToString())
.ToArray();
Console.WriteLine(" {0}", string.Join(", ", propValues));
}
但是您必须决定序列化格式和目的地,也许您可以使用某种通用序列化器,而不是我在这里解释的手动逗号分隔值。
在我的 EF6 应用程序上,我想显示当前在我的数据库中的所有实体的所有行。有没有一种方法可以做到这一点而不必知道我的实体是什么以及这些实体的属性是什么?我认为使用反射是解决这个问题的方法,但我无法找到解决方案。有什么想法吗?
更新:回复人们的问题... 数据库是SQLSERVER。 我不明白我想在这里具体实现的目标有何相关性。它甚至可以用于编写例程以查看所有数据的练习。 至于安全原因,例如,如果我想通过应用程序管理安全性或授予某人管理员权限以随心所欲地管理数据库,我不明白为什么这是一个设计问题。 看到所有已发布的链接,但到目前为止所有这些链接,解决方案包括构建 sql 语句,这是我想要摆脱的。
所以作为一个简单的例子并总结我的求助,我想要的是通过 c#,使用 Entity framework 和 Linq,能够编写一个执行 "show me everything" 命令的方法茉莉花谈起。 可能是因为我决定不喜欢字母 "a" 并想从数据库中清除它。 可能是因为我想查找所有包含单词 "fido" 的记录 一些地方。 可能是因为我想知道我的数据库有多少 words/numbers。 像这样,我想要这样做的原因还有很多,尽管就像我说的那样我觉得它无关紧要。
唯一的方法是获取 DbContext
中定义的所有实体,获取每个实体的 Set
,然后序列化实体(您没有指定格式) 并将其写入文件或您想要存储结果的任何位置。
public void GetDbSets(DbContext ctx)
{
// Initialize, to build the metadata
ctx.Database.Initialize(true);
// Access the underlying ObjectContext
var objectContext = ((IObjectContextAdapter)ctx).ObjectContext;
// Get the metadata for the DbContext
MetadataWorkspace mdw = objectContext.MetadataWorkspace;
// get the assembly, where the entity types are defined
var asm = ctx.GetType().Assembly;
// Get the metadata for the entity types
ReadOnlyCollection<EntityType> entityTypes
= mdw.GetItems<EntityType>(DataSpace.CSpace);
foreach (var et in entityTypes)
{
var type = asm.GetType(et.FullName);
Console.WriteLine("{0}: {1}", et.FullName,
string.Join(", ", et.Members.Select(m => m.Name).ToArray()));
var dbEntries = ctx.Set(type).AsNoTracking().AsQueryable();
foreach (var e in dbEntries)
{
var propValues = et.Members
.Select(m => type.GetProperty(m.Name).GetValue(e).ToString())
.ToArray();
Console.WriteLine(" {0}", string.Join(", ", propValues));
}
}
}
注意:代码未优化。每当你使用反射时,你应该缓存 PropertyInfo
s 以重用它们,而不是一遍又一遍地获取它们。此代码有效,但未优化。例如,对于内部循环,您可以这样做:
var propInfos = new Dictionary<string, PropertyInfo>();
et.Members.ForEach(m => propInfos.Add(m.Name, type.GetProperty(m.Name)));
foreach (var e in dbEntries)
{
var propValues = et.Members
.Select(m => propInfos[m.Name].GetValue(e).ToString())
.ToArray();
Console.WriteLine(" {0}", string.Join(", ", propValues));
}
但是您必须决定序列化格式和目的地,也许您可以使用某种通用序列化器,而不是我在这里解释的手动逗号分隔值。