2016-07-22 61 views
0

目前,我正在手動向對象添加屬性和值,如示例,併發送到Dapper.SimpleCRUD以從Dapper Orm中獲取數據。這是我想達到的想要的輸出使用C#動態構建強類型對象?

object whereCriteria = null; 
whereCriteria = new 
{ 
    CountryId = 2, 
    CountryName = "Anywhere on Earth", 
    CountryCode = "AOE", 
    IsActive = true 
}; 

下面的類應該以上述格式構建對象並返回現成的對象。

public static class WhereClauseBuilder 
{ 
    public static object BuildWhereClause(object model) 
    { 
     object whereObject = null; 
     var properties = GetProperties(model); 

     foreach (var property in properties) 
     { 
      var value = GetValue(property, model); 

      //Want to whereObject according to the property and value. Need help in this part!!! 
     } 

     return whereObject; 
    } 

    private static object GetValue(PropertyInfo property, object model) 
    { 
     return property.GetValue(model); 
    } 

    private static IEnumerable<PropertyInfo> GetProperties(object model) 
    { 
     return model.GetType().GetProperties(); 
    } 
} 

此功能WhereClauseBuilder.BuildWhereClause(object model)預期格式(mentiond上文)返回對象。這是我想如何使用的實現。

public sealed class CountryModel 
{ 
    public int CountryId { get; set; } 
    public string CountryName { get; set; } 
    public string CountryCode { get; set; } 
    public bool IsActive { get; set; } 
} 

public class WhereClauseClass 
{ 
    public WhereClauseClass() 
    { 
     var model = new CountryModel() 
     { 
      CountryCode = "AOE", 
      CountryId = 2, 
      CountryName = "Anywhere on Earth", 
      IsActive = true 
     }; 

     //Currently, won't return the correct object because the implementation is missing. 
     var whereClauseObject = WhereClauseBuilder.BuildWhereClause(model); 
    } 
} 
+0

此鏈接[http://msdn.microsoft.com/en-us/library/system.activator.createinstance(VS.71).aspx](http://msdn.microsoft.com/en-us/ library/system.activator.createinstance(VS.71).aspx)會幫助你。 – Thennarasan

+0

謝謝,我已經看到了這個鏈接。但是,我很好奇知道如何構建可以以所需格式返回的對象? –

+0

我不明白你想要做什麼。您可以創建一個[ExpandoObject](https://msdn.microsoft.com/de-de/library/system.dynamic.expandoobject(v = vs.110).aspx)的實例並將其與動態配合使用,我不確定這是你想要的。另一種方法是創建一個代碼模板,其中包含所有需要的名稱空間和類體,並填寫屬性定義。有了這個,你可以在運行時編譯代碼並創建對象的一個​​實例。在這種情況下,Microsoft.CSharp將幫助你。 –

回答

1

也許這樣的事情:

private const string CodeTemplate = @" 
    namespace XXXX 
    { 
     public class Surrogate 
     { 
    ##code## 
     } 
    }"; 

public static Type CreateSurrogate(IEnumerable<PropertyInfo> properties) 
{ 
    var compiler = new CSharpCodeProvider(); 
    var compilerParameters = new CompilerParameters { GenerateInMemory = true }; 
    foreach (var item in AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.IsDynamic)) 
    { 
     compilerParameters.ReferencedAssemblies.Add(item.Location); 
    } 

    var propertiesCode = 
     string.join("\n\n", from pi in properties 
          select "public " + pi.PropertyType.Name + " " + pi.Name + " { get; set; }"); 

    var source = CodeTemplate.Replace("##code##", propertiesCode); 

    var compilerResult = compiler.CompileAssemblyFromSource(compilerParameters, source); 
    if (compilerResult.Errors.HasErrors) 
    { 
     throw new InvalidOperationException(string.Format("Surrogate compilation error: {0}", string.Join("\n", compilerResult.Errors.Cast<CompilerError>()))); 
    } 

    return compilerResult.CompiledAssembly.GetTypes().First(x => x.Name == "Surrogate"); 
} 

現在使用它:

public static object BuildWhereClause(object model) 
{ 
    var properties = GetProperties(model); 
    var surrogateType = CreateSurrogate(properties); 
    var result = Activator.CreateInstance(surrogateType); 

    foreach (var property in properties) 
    { 
     var value = GetValue(property, model); 
     var targetProperty = surrogateType.GetProperty(property.Name); 
     targetProperty.SetValue(result, value, null); 
    } 

    return result; 
} 

我沒有編譯。它只寫在這裏。也許有一些錯誤。 :-)

編輯:

要使用ExpandoObject你可以試試這個:

public static object BuildWhereClause(object model) 
{ 
    var properties = GetProperties(model); 
    var result = (IDictionary<string, object>)new ExpandoObject(); 

    foreach (var property in properties) 
    { 
     var value = GetValue(property, model); 
     result.Add(property.Name, value); 
    } 

    return result; 
} 

但我不知道這是否會爲你工作。

+0

我正在建議'ExpandoObject'並將其轉換爲字典,但是我看到您已將它添加到您的更新中。 – Nkosi

+0

謝謝你們。我想我無法將'ExpandoObject'轉換爲我想要的輸出。也許,有一種方法,我不知道? –

+0

@CoderAbsolute你需要什麼輸出類型?您也將有問題轉換動態創建的代理。 –