簡體   English   中英

C#如何從列表中返回1行<T>作為參數傳遞的對象

[英]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字段,這是您嘗試匹配的屬性。

  1. 定義一個可重用的接口:
public interface ICodeEntity
{
    string Code { get; }
}
  1. 將您的接口應用於您打算用於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
}
  1. 添加一個泛型類型約束,將T的使用限制為僅用於實現您的接口的類型。
public static List<T> Selectus<T>(string code)
    where T : ICodeEntity
  1. 您現在可以以依賴於具有Code屬性的相關類型的方式編寫代碼,並且編譯器將幫助執行它。
var db = OrmLiteBaza().Open();
var list = db.Select<T>().ToList();            
db.Dispose();

return list.Where(item => item.Code == code).ToList();
  1. 使用示例:
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");

如何從列表轉換<object>列出<t>在 c# 中?<div id="text_translate"><p> 我有一個 Class:</p><pre> public class Element { public List&lt;object&gt; objects { get; set; } }</pre><p> 還有一個 Class:</p><pre> public class Node { public long id { get; set; } }</pre><p> 我傳入一個List&lt;object&gt; nodes 。 那么有什么方法可以將這些List&lt;object&gt; objects轉換為List&lt;Node&gt; nodes ?</p><p> 我試過這種方式,但它不起作用List&lt;Node&gt; nodes = objects.Select(s =&gt; (nodes)s).ToList();</p></div></t></object>

[英]How to convert from List<object> to List<T> in c#?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM