![](/img/trans.png)
[英]C# - How to return a Generic List based on a passed parameter to the Method
[英]C# how to return 1 row from List<T> object passed as parameter
我需要從我的函數 Selectus 返回一行列表。
所以我傳遞給反映數據庫表字段的函數 Selectus 對象,我需要返回與參數looking_for 匹配的一行:
public static List<T> Selectus<T>(string looking_for)
{
//all select data
var db = OrmLiteBaza().Open();//opening database
var select_all_list = db.Select<T>();//getting all data for <T> object works fine
db.Dispose();
//try to select one row - here I have trouble:
var prop = typeof(T).GetProperties();//properties of passed <T> object
var list_selected_record = from records in select_all_list where prop[1].Name == looking_for select records;//tryin to select one record from <T> object as in looking_for variable
return list_selected_record.ToList();//here one record should be returned
}
假設 T 參數不同,我不知道如何從列表中選擇一行。 在 SelectusT> 方法中,我想將反映數據庫表中字段的不同對象作為 T 傳遞,而不是為每個選擇創建單獨的方法。 例如調用 Selectus,其中傳遞的對象是 public class ProductCodes { public int ID { get; 放; } 公共字符串 SapIndex { 獲取; 放; } 公共字符串 SapName { 獲取; 放; } }。 然后我想為另一個表調用另一個Selectus<ProductTypes>
等等......所以我想編寫通用/整體方法並將其普遍用於我的所有類型的對象,這反映了幾個數據庫表的字段。 SapIndex 屬性始終位於所有對象的相同位置...
使用prop[1]
非常脆弱。 誰說你目前感興趣的房產總是排在第二位? 如果有人明天添加另一個屬性怎么辦? 如果不是您使用的每個 T 在其屬性列表中的第二位都具有相同的屬性怎么辦? 目前還不清楚你的實際目標是什么,以及你為什么要采取反思路線。
你最好在這里使用繼承或接口實現。 我將在這個答案中使用一個界面,但任何一個都可以。
為了清楚起見,我們假設在所有可能的列表中都有一個Code
字段,這是您嘗試匹配的屬性。
public interface ICodeEntity
{
string Code { get; }
}
Selectus
方法的所有類。public class Person : ICodeEntity
{
public string Code { get; set; }
// And other properties
}
public class Document : ICodeEntity
{
public string Code { get; set; }
// And other properties
}
T
的使用限制為僅用於實現您的接口的類型。public static List<T> Selectus<T>(string code)
where T : ICodeEntity
Code
屬性的相關類型的方式編寫代碼,並且編譯器將幫助執行它。var db = OrmLiteBaza().Open();
var list = db.Select<T>().ToList();
db.Dispose();
return list.Where(item => item.Code == code).ToList();
List<Person> peopleWithCodeABC = Selectus<Person>("ABC");
List<Person> documentsWithCodeXYZ = Selectus<Document>("XYZ");
// This will fail if Animal does not implement ICodeEntity
var compilerError = Selectus<Animal>("ABC");
您可以更改代碼以僅返回一個元素
public static T Selectus<T>(string looking_for)
{
//all select data
var db = OrmLiteBaza().Open();//opening database
var select_all_list = db.Select<T>();//getting all data for <T> object works fine
db.Dispose();
//try to select one row - here I have trouble:
var prop = typeof(T).GetProperties();//properties of passed <T> object
var list_selected_record = from records in select_all_list where prop[1].Name == looking_for select records;//tryin to select one record from <T> object as in looking_for variable
return list_selected_record.FirstOrDefault();//here one record should be returned
}
我可能不完全理解您想要的內容,但是您可以通過func Func<,>
代表的委托,而不是string looking_for
。
就像是:
public static List<TField> Selectus<T, TField>(Func<T, TField> selector)
{
var db = OrmLiteBaza().Open();
var select_all_list = db.Select<T>();
db.Dispose();
var list_selected_record = select_all_list.Select(selector); // 'using System.Linq;'
return list_selected_record.ToList();
}
然后我相信它可以這樣稱呼:
var list_one = Selectus((ProductCodes x) => x.SapIndex);
var list_two = Selectus((ProductTypes x) => x.SapIndex);
var list_three = Selectus((ProductCodes x) => x.SapName);
使用這種語法,我省略了該方法的<ProductCodes, string>
通用參數,因為它們可以被推斷出來。
嗯,也許你想要它在相反的維度。 你可以這樣做:
public static List<T> Selectus<T>(Func<T, bool> predicate)
{
var db = OrmLiteBaza().Open();
var select_all_list = db.Select<T>();
db.Dispose();
var list_selected_record = select_all_list.Where(predicate); // 'using System.Linq;'
return list_selected_record.ToList();
}
和:
var list_one = Selectus((ProductCodes x) => x.SapIndex == "ABC");
var list_two = Selectus((ProductTypes x) => x.SapIndex == "ABC");
var list_three = Selectus((ProductCodes x) => x.SapName == "DaName");
或者:
var list_one = Selectus<ProductCodes>(x => x.SapIndex == "ABC");
var list_two = Selectus<ProductTypes>(x => x.SapIndex == "ABC");
var list_three = Selectus<ProductCodes>(x => x.SapName == "DaName");
但是,如果它始終是“相同”的屬性,就像x.SapIndex
一樣(但對於不同類型的x
),那么 Flater 的答案看起來不錯。
否則,如果你堅持,你的反思方法應該是可能的。 使用屬性的名稱,而不是它的索引! 讓我試試:
public static List<T> Selectus<T>(string looking_for)
{
var db = OrmLiteBaza().Open();
var select_all_list = db.Select<T>();
db.Dispose();
const string prop_name = "SapIndex";
var prop = typeof(T).GetProperty(prop_name); // can blow up for bad T
var list_selected_record = select_all_list
.Where(x => (string)(prop.GetValue(x)) == looking_for); // 'using System.Linq;'
return list_selected_record.ToList();
}
和:
var list_one = Selectus<ProductCodes>("ABC");
var list_two = Selectus<ProductTypes>("ABC");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.