Common method and anonymous types

Is it possible to create a code like this:

private static string GetInsertString<TDto>() { var type = typeof(TDto); var properties = type.GetProperties().Where(Where); var tableName = type.Name; return string.Format("INSERT INTO {0} ({1}) VALUES ({2});", tableName, string.Join(",", properties.Select(x => x.Name).ToArray()), string.Join(",", properties.Select(x => string.Format("@{0}", x.Name.ToLower())).ToArray())); } 

which works with anonymous types:

 var point = new { X = 13, Y = 7 }; 

PS:

Output:

 INSERT INTO Anonymous (X, Y) values (13, 7) 

Of course, you can specify a table name.

+6
source share
4 answers

Assuming you are using .net 4.0 or higher, you can use dynamic and ExpandoObject as follows:

 private static string GetInsertString(dynamic obj) { var expando = (ExpandoObject)obj; return string.Format("INSERT INTO {0} ({1}) VALUES ({2});", "tableName", string.Join(",", expando.Select(x => x.Key)), string.Join(",", expando.Select(x => x.Value is string ? "'" + x.Value + "'" : x.Value.ToString()))); } 

And then:

 dynamic o = new ExpandoObject(); oa = 10; ob = "hello"; var s = GetInsertString(o); 

Now s is INSERT INTO tableName (a,b) VALUES (10,'hello'); . This is just a draft that you must follow to get the correct insert string.

+2
source

You cannot specify a type parameter with an anonymous type, but if you pass it an object as a parameter, you can use the type inference to hold the type:

 private static string GetInsertString<TDto>(TDto dto) { var type = typeof(TDto); var propertyNames = type.GetProperties().Where(Where).Select(x => x.Name); return string.Format("INSERT INTO {0} ({1}) VALUES ({2});", type.Name, string.Join(",", propertyNames), string.Join(",", propertyNames.Select(x => string.Format("@{0}", x.ToLower()))); } 

Then call the method: var insertString = GetInsertString(new { X = 13, Y = 7 });

+4
source

It is very difficult to use anonymous types using the ...<T>() method. The main way to do this includes an example of hacking, i.e.

 var dummy = new { X = 13, Y = 7 }; Foo(dummy); // for Foo<T>(T obj) 

or more succinctly:

 Foo(new { X = 13, Y = 7 }); 

which uses generic type inference to output T here of an anonymous type. Foo<T>(T obj) can be your actual method or it can be a method that in turn calls GetInsertString<TDto>() , i.e.

 // overload that takes an example object as a parameter private static string GetInsertString<TDto>(TDto example) { return GetInsertString<TDto>(); } 

Perhaps you can also combine the two:

 private static string GetInsertString<TDto>(TDto example = null) { .. your code .. } 

and give an example only when necessary.

However, the β€œby example” approach is fragile and susceptible to cracking. I highly recommend you simply define POCO:

 public class MyType { public int X {get;set;} public int Y {get;set;} } 

and use GetInsertString<MyType> .

+3
source

You can use anonymous objects using common methods if the compiler can resolve the type. For example, if it can be resolved from a parameter. Like this:

 private static string GetInsertString<TDto>(TDto someObject) { var type = typeof(TDto); var properties = type.GetProperties(); // Removed .Where(Where) since it didn't compile var tableName = type.Name; return string.Format( "INSERT INTO {0} ({1}) VALUES ({2});", tableName, string.Join(",", properties.Select(x => x.Name).ToArray()), string.Join(",", properties.Select(x => string.Format("@{0}", x.Name.ToLower())).ToArray()) ); } var point = new { X = 13, Y = 7 }; var insertSql = Test.GetInsertString(point); // Results in: INSERT INTO <>f__AnonymousType0`2 (X,Y) VALUES (@x,@y); 
0
source

Source: https://habr.com/ru/post/971325/


All Articles