我正在使用Dapper将2列结果集提取到字典中.我注意到当我将鼠标悬停在结果集上时,intellisense向我显示了一个.ToDictionary(),但由于dapper使用动态属性/ expandoObject,我无法使其工作
Dictionary<string, string > rowsFromTableDict = new Dictionary<string, string>();
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
var results = connection.Query
("SELECT col1 AS StudentID, col2 AS Studentname
FROM Student order by StudentID");
if (results != null)
{
//how to eliminate below foreach using results.ToDictionary()
//Note that this is results<dynamic, dynamic>
foreach (var row in results)
{
rowsFromTableDict.Add(row.StudentID, row.StudentName);
}
return rowsFromTableDict;
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢
我需要在C#中"合并"2个动态对象.我在stackexchange上发现的所有内容都只包含非递归合并.但我正在寻找一些递归或深度合并的东西,就像jQuery的$.extend(obj1, obj2)
功能一样.
两名成员发生碰撞后,应遵守以下规则:
IEnumerable
与IEnumberables<T>
简单地合并(也许.Concat()
?)IDictionary
与IDictionary<TKey,TValue>
合并; obj1键在碰撞时具有优先权Expando
&Expando[]
types必须递归合并,而Expando []将始终只有相同类型的元素以下是可能合并的示例:
dynamic DefaultConfig = new {
BlacklistedDomains = new string[] { "domain1.com" },
ExternalConfigFile = "blacklist.txt",
UseSockets = new[] {
new { IP = "127.0.0.1", Port = "80"},
new { IP = "127.0.0.2", Port = "8080" }
}
};
dynamic UserSpecifiedConfig = new {
BlacklistedDomain = new string[] { "example1.com" },
ExternalConfigFile = …
Run Code Online (Sandbox Code Playgroud) 我正在尝试在Scala中实现C#的ExpandoObject
类.这是它应该如何工作:
val e = new ExpandoObject
e.name := "Rahul" // This inserts a new field `name` in the object.
println(e.name) // Accessing its value.
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所尝试的:
implicit def enrichAny[A](underlying: A) = new EnrichedAny(underlying)
class EnrichedAny[A](underlying: A) {
// ...
def dyn = new Dyn(underlying.asInstanceOf[AnyRef])
}
class Dyn(x: AnyRef) extends Dynamic {
def applyDynamic(message: String)(args: Any*) = {
new Dyn(x.getClass.getMethod(message,
args.map(_.asInstanceOf[AnyRef].getClass) : _*).
invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*))
}
def typed[A] = x.asInstanceOf[A]
override def toString = "Dynamic(" + x …
Run Code Online (Sandbox Code Playgroud) 我正在使用expando对象,我正在尝试定义计算属性.
我知道我可以通过执行以下操作来定义一个简单的属性:
dynamic myExpando = new ExpandoObject();
myExpando.TheAnswerToLifeTheUniverseAndEverything= 42;
Run Code Online (Sandbox Code Playgroud)
同样,我也可以定义一个方法:
myExpando.GetTheQuestion = ((Func<string>)(() =>
{
return "How many road must a man walk down before we can call him a man?";
}));
Run Code Online (Sandbox Code Playgroud)
使用标准对象时,我们可以定义计算属性,即定义将返回自定义方法/计算结果的属性.不需要一个例子.
我需要在我的expando上做类似的事情 - 拥有一个实际调用"Func"的属性(或者其他形式的委托,只要我可以调用自定义方法并且具有自定义返回类型,任何事情都会发生).所以基本上我需要像第二个例子那样调用一个方法,但是它有点像属性一样工作.
基本上我需要能够用myExpando.GetTheQuestion而不是myExpando.GetTheQuestion()来调用它,同时保持定义自定义委托作为属性体的能力.
有没有办法做到这一点?我相信我可以通过使用表达式树来做到这一点,但我承认我在那里有点失落.谁能提供一些如何实现这一目标的指导?
编辑
做了一些更多的研究..除非有一些非常具体的类/接口/ sintax,我不知道我开始认为上述是不可能的.从我得到的,ExpandoObject类的工作原理是定义一些执行后台管道的方法 - TryGetMember,TrySetMember等.现在,在动态对象上"访问属性"时,TryGetMember是被调用的成员.该成员从一种内部字典返回一个值(是的,我知道......这有点简化,但应该给出这个想法)......没有对返回的值类型进行测试.这意味着在我的示例中myExpando.GetTheQuestion将返回原始Func.
看来,由于TryGetMember只返回一个值,因此无法使其"执行"属性代码.要实现这一点,您需要某种表达式/ lambda/func/action代理,该值实际上是方法的结果.这似乎是不可能的(除非我错过了某些东西,否则也没有多大意义 - 基本上你会有一个设置为'委托'的值,然后作为委托返回值得到???).我是正确还是这个还是我遗失了什么?
我有一个ExpandoObject,我发送到一个外部库方法,它接受一个对象.从我看到的这个外部lib内部使用TypeDescriptor.GetProperties,这似乎导致我的ExpandoObject的一些问题.
我可以改为使用匿名对象,这似乎有效但我使用ExpandoObject更方便.
我是否需要构建自己的DynamicObject并通过实现ICustomTypeDescriptor自己处理它,或者我在这里遗漏了一些东西.
想法?
更新
除了以下somedave的回答(根据评论),我添加了这个类
public class ExpandoObjectTypeDescriptionProvider : TypeDescriptionProvider
{
private static readonly TypeDescriptionProvider m_Default = TypeDescriptor.GetProvider(typeof(ExpandoObject));
public ExpandoObjectTypeDescriptionProvider()
:base(m_Default)
{
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
var defaultDescriptor = base.GetTypeDescriptor(objectType, instance);
return instance == null ? defaultDescriptor :
new ExpandoObjectTypeDescriptor(instance);
}
}
Run Code Online (Sandbox Code Playgroud)
并注册如下:
dynamic parameters = new ExpandoObject();
TypeDescriptor.AddProvider(new ExpandoObjectTypeDescriptionProvider(), parameters);
Run Code Online (Sandbox Code Playgroud) 这是一个非常具体的问题.不太确定如何说出来.基本上我正在实现工作单元和存储库模式,我有一个动态对象,我转换为int,但如果我使用var
它将在尝试调用方法时抛出异常.
我试图删除所有这些问题,我可以解决这个问题.出于某种原因,我只看到这两种设计模式.我得到的例外是Additional information: 'BlackMagic.ITacoRepo' does not contain a definition for 'DoStuff'
这是代码:
class BlackMagic
{
static void Main(string[] args)
{
dynamic obj = new ExpandoObject();
obj.I = 69;
UnitOfWork uow = new UnitOfWork();
int i1 = Convert.ToInt32(obj.I);
var i2 = Convert.ToInt32(obj.I);
if(i1.Equals(i2))
{
uow.TacoRepo.DoStuff(i1); // Works fine
uow.TacoRepo.DoStuff(i2); // Throws Exception
}
}
}
class UnitOfWork
{
public ITacoRepo TacoRepo { get; set; }
public UnitOfWork()
{
TacoRepo = new TacoRepo();
}
}
class Repo<T> : IRepo<T> …
Run Code Online (Sandbox Code Playgroud) c# unit-of-work repository-pattern expandoobject dynamicobject
首先,我将txt文件读入文件夹,然后用expando对象水合对象.
但是现在我想从这些对象中获取一些值来填充listview(winforms).
private void Form1_Load(object sender, EventArgs e)
{
string pattern = "FAC*.txt";
var directory = new DirectoryInfo(@"C:\\TestLoadFiles");
var myFile = (from f in directory.GetFiles(pattern)
orderby f.LastWriteTime descending
select f).First();
hydrate_object_from_metadata("FAC",listBox3);
hydrate_object_from_metadata("BL", listBox4);
this.listBox3.MouseDoubleClick += new MouseEventHandler(listBox3_MouseDoubleClick);
this.listBox1.MouseClick += new MouseEventHandler(listBox1_MouseClick);
}
void hydrate_object_from_metadata(string tag, ListBox listBox)
{
SearchAndPopulateTiers(@"C:\TestLoadFiles", tag + "*.txt", tag);
int count = typeDoc.Count(D => D.Key.StartsWith(tag));
for (int i = 0; i < count; i++)
{
object ob = GetObject(tag + i);
///HERE I WOULD LIKE GET …
Run Code Online (Sandbox Code Playgroud) 我有一个名为products的expando对象的简单列表.
我在运行时向这些对象添加各种字段(例如颜色或大小)
如何根据动态字段在此列表上编写LINQ查询?
使用经典的对象列表,我可以编写如下的LINQ查询:
From item in Products Where item.color="red" select item
Run Code Online (Sandbox Code Playgroud)
但是对于expandos,如何实现这一点,知道我事先并不知道字段的名称(它可能是重量或其他任何东西)?
先感谢您.
给出下面的代码
dynamic e = new ExpandoObject();
var d = e as IDictionary<string, object>;
for (int i = 0; i < rdr.FieldCount; i++)
d.Add(rdr.GetName(i), DBNull.Value.Equals(rdr[i]) ? null : rdr[i]);
Run Code Online (Sandbox Code Playgroud)
有没有办法让它不区分大小写,所以给定字段名称employee_name
e.Employee_name与e.employee_name一样有效
似乎没有一个明显的方式,也许是一个黑客?
我已经阅读了很多关于如何使用ExpandoObject通过添加属性从头开始动态创建对象的内容,但我还没有发现你是如何从已经拥有的非动态C#对象开始做同样的事情的.
例如,我有这个琐碎的课程:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Telephone { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想将它转换为ExpandoObject,以便我可以根据已经的内容添加或删除属性,而不是从头开始重建相同的东西.这可能吗?
编辑:标记为重复的问题显然不是这个问题的重复.