在我的EF6应用程序上,我想显示当前在我的数据库中的所有实体的所有行。有没有办法做到这一点,而不必知道我的实体是什么以及这些实体的属性是什么?我认为使用反射是解决这个问题的方法,但我无法解决问题。任何想法?
更新:回复人们的要求...... 该数据库是SQLSERVER。 我不知道我想在这里具体实现的是多么重要。它甚至可以用于编写例程来查看所有数据。 出于安全原因,如果我想通过应用程序管理安全性或者给予管理员权限来管理数据库,那么我不明白为什么这是一个设计问题。 看到发布的所有链接,但到目前为止所有链接,解决方案包括构建sql语句,这是我想要摆脱的。
所以作为一个简单的例子,并且为了帮助我的帮助,我想要的是通过c#,使用Entity框架和Linq,能够编写一个方法来执行Jasmine所说的“show me everything”命令。 这可能是因为我决定不喜欢字母“a”并希望从数据库中清除它。 这可能是因为我想查找包含“fido”一词的所有记录 一些地方。 这可能是因为我想找到我的数据库有多少单词/数字。 就像这样,有很多理由让我想要做到这一点,即使我说我发现它无关紧要。
答案 0 :(得分:0)
这样做的唯一方法是获取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
以重复使用它们,而不是一遍又一遍地重复它们。此代码有效,但未进行优化。例如,对于内循环,您可以这样做:
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));
}
但是你必须决定序列化格式,目标和perhasp你可以使用某种通用序列化器,而不是我在这里解释的手动逗号分隔值。