ඩේටා ටේබල් එකක ලින්ක් විමසුම


1040

මම ඩේටා ටේබල් වස්තුවක් මත ලින්ක් විමසුමක් සිදු කිරීමට උත්සාහ කරන අතර විකාර සහගත ලෙස ඩේටා ටේබල්ස් හි එවැනි විමසුම් සිදු කිරීම සරල නොවන බව මට පෙනී යයි. උදාහරණයක් වශයෙන්:

var results = from myRow in myDataTable
where results.Field("RowNo") == 1
select results;

මෙය අවසර නැත. මේ වගේ වැඩක් කරන්නේ කොහොමද?

ඩේටා ටේබල්ස් හි ලින්ක් විමසුම් වලට ඉඩ නොදීම ගැන මම පුදුම වෙමි!


Answers:


1287

ඔබ එරෙහිව විමසුම කළ නොහැකි DataTableගේ පේළි සිට, එකතු DataRowCollectionක්රියාත්මක කරන්නේ නැත IEnumerable<T>. ඔබ සඳහා AsEnumerable()දිගුව භාවිතා කළ යුතුය DataTable. එසේ වැනි:

var results = from myRow in myDataTable.AsEnumerable()
where myRow.Field<int>("RowNo") == 1
select myRow;

ලෙස @Keith පවසයි, ඔබ වෙත යොමු එකතු කිරීම අවශ්ය වේ System.Data.DataSetExtensions

AsEnumerable()ප්‍රතිලාභ IEnumerable<DataRow>. ඔබට IEnumerable<DataRow>a බවට පරිවර්තනය කිරීමට අවශ්‍ය නම් DataTable, භාවිතා කරන්නCopyToDataTable() දිගුව .

පහත දැක්වෙන්නේ ලැම්බඩා ප්‍රකාශනය සමඟ විමසුම,

var result = myDataTable
    .AsEnumerable()
    .Where(myRow => myRow.Field<int>("RowNo") == 1);

8
VB අනුවාදය: අඳුරු ප්‍රති results ල = myRow වෙතින් myDataTable.AsEnumerable _ කොහෙද myRow.Field ("RowNo") = 1 _ myRow තෝරන්න
ජෙෆ්

15
මා දැනටමත් සඳහන් කර ඇති ඩීඑල් ගැන සඳහනක් කර ඇත, නමුත් අතුරුදහන් වියusing System.Data;
ලූක් ඩඩ්රිජ්

5
VB අනුවාදයට myRow.Field සහ ("RowNo") අතර (නූල්) ඇතුළත් කළ යුතුය. එම කොටස කියවිය යුතුය: myRow.Field (Of String) ("RowNo") = 1 - යොමු @ ක්‍රොස් අදහස්.
yougotiger

8
මෙම විසඳුම අනවශ්‍ය ලෙස සංකීර්ණ වේ. myDataTable.RowsO ජොයෙල්ෆාන් යෝජනා කළ පරිදි ඒ වෙනුවට භාවිතා කරන්න .
කුමන්ත්‍රණය

10
Ark මාකස් පැහැදිලි කිරීම සඳහා, @ ජොයෙල්ෆාන් ගේ විසඳුම සමඟ ක්‍රියා කිරීමට myDataTable.Rowsහේතුව වන්නේ myRowවිචල්‍යය පැහැදිලිවම වාත්තු කිරීමයි DataRow. එය සම්පාදනය කළ විට, එම විමසුම නැවත ලියනු ලැබේ myDataTable.Rows.Cast<DataRow>().Where(myRow => (int)myRow["RowNo"] == 1). පුද්ගලිකව, ඇමතුමට AsEnumerable()වඩා සංකීර්ණ ඇමතුමක් මට හමු නොවේ Cast<DataRow>(). මා දන්නා පරිදි, කාර්ය සාධනය සමාන වේ, එබැවින් එය මනාපයක් පමණි.
කොලින් කේ

130
var results = from DataRow myRow in myDataTable.Rows
    where (int)myRow["RowNo"] == 1
    select myRow

2
1 වන පේළිය වෙනුවට පේළි කිහිපයක් තෝරා ගැනීම ගැන කුමක් කිව හැකිද?
Adjit

2
"කොහේද" යන රේඛාව ඉවත් කරන්න, එවිට ඔබට සියලු පේළි ලැබෙනු ඇත
ජොයෙල්ෆාන්

2
ඔව්, මම එය කිරීමට භාවිතා කරන්නේ එලෙසයි (int)myRow["RowNo"], සාමාන්‍ය ආකෘති පත්රය myRow.Field<int>("RowNo")වෙනුවට වඩාත් පහසු ආධාරක වර්ග සඳහා ආදේශ කිරීම හැර .
ජොනාස්

69

ඩේටා ටේබල්ස් හි ඔවුන්ට හිතාමතාම ඉඩ නොදුන් බවක් නොවේ, එය ඩේටා ටේබල්ස් විසින් ලින්ක් විමසුම් සිදු කළ හැකි IQueryable සහ generic IEnumerable ඉදිකිරීම් වලට පෙර දින නියම කිරීම පමණි.

අතුරුමුහුණත් දෙකටම යම් ආකාරයක ආරක්‍ෂිත වලංගුතාවයක් අවශ්‍ය වේ. දත්ත ටේබල් දැඩි ලෙස ටයිප් කර නැත. උදාහරණයක් ලෙස අරා ලැයිස්තුවකට එරෙහිව මිනිසුන්ට විමසීමට නොහැකි වීමට හේතුව මෙයයි.

ලින්ක් වැඩ කිරීමට නම්, ඔබේ ප්‍රති results ල ටයිප්-ආරක්ෂිත වස්තූන් සමඟ සිතියම් ගත කළ යුතු අතර ඒ වෙනුවට විමසන්න.


50

00 ch00k පැවසූ පරිදි:

using System.Data; //needed for the extension methods to work

...

var results = 
    from myRow in myDataTable.Rows 
    where myRow.Field<int>("RowNo") == 1 
    select myRow; //select the thing you want, not the collection

ඔබට ව්‍යාපෘති යොමු කිරීමක් ද එක් කළ යුතුය System.Data.DataSetExtensions


1
ඔබ මෙය උත්සාහ කළහොත්, ඔබ විශේෂිත වර්ගයක් දමා myRowහෝ භාවිතා නොකරන්නේ නම් එය ක්‍රියා නොකරනු Cast<DataRow>()ඇත Rows. භාවිතා කිරීමට වඩා හොඳය AsEnumerable().
NetMage

1
EtNetMage මීට වසර 12 කට පෙර මම එය පළ කරන විට මෙය ක්‍රියාත්මක විය. ඔබ දීර්ඝ කාලයක් ලෙස System.Linqහා System.Data.DataSetExtensionsපසුව myDataTable.Rowsක ගණ්ය එකතුව නැවත DataRowකෙසේ හෝ. එය වෙනස් වන්නට ඇත, මම එය භාවිතා කර දශකයක් ගත වී ඇත.
කීත්

1
සිත්ගන්නා සුළුය - එය දැන් .Net හෝ .Net Core මත ක්‍රියා නොකරන බැවින් එය යම් අවස්ථාවක වෙනස් කර ඇති බව මම අනුමාන කරමි.
NetMage

1
EtNetMage ඔව්, DataSetදිගු කිරීම .NET Core හෝ .NET Standard බවට පත් නොකිරීම ගැන මම පුදුම නොවෙමි, මම මෙම පිළිතුර පළ කරන විට ඒවා දැනටමත් යල් පැන ගොස් ඇත. මම DataSetනව ව්‍යාපෘති වල භාවිතා නොකරමි , කේතීකරණයේ පහසුව සහ ක්‍රියාකාරීත්වය යන දෙකටම වඩා හොඳ දත්ත ප්‍රවේශ ආකෘති තිබේ.
කීත්

1
ඒවා එහි ඇත, නමුත් සාධාරණ ලෙස DataRowCollectionක්‍රියාත්මක නොවන අතර දැඩි ලෙස ටයිප් කළ LINQ සමඟ ක්‍රියා නොකරයි. IEnumerable<T>IEnumerable
NetMage

39
var query = from p in dt.AsEnumerable()
                    where p.Field<string>("code") == this.txtCat.Text
                    select new
                    {
                        name = p.Field<string>("name"),
                        age= p.Field<int>("age")                         
                    };

නම සහ වයස් ක්ෂේත්‍ර දැන් විමසුම් වස්තුවෙහි කොටසක් වන අතර ඒවාට ප්‍රවේශ විය හැකිය: Console.WriteLine (query.name);


මම නම භාවිතා කරන්නේ කෙසේද? උදාහරණයක් ලෙස, MessageBox.Show(name)නිර්වචනය කර නැත.

35

මට කිහිප වතාවක්ම පිළිතුරු දී ඇති බව මට වැටහී ඇත, නමුත් වෙනත් ප්‍රවේශයක් ඉදිරිපත් කිරීම සඳහා:

මම .Cast<T>()ක්‍රමවේදය භාවිතා කිරීමට කැමතියි , එය පැහැදිලිව දක්වා ඇති වර්ගය නිර්වචනය කර ඇති අතර එය ගැඹුරින් බැලූ බැල්මට එය සනීපාරක්ෂාව පවත්වා ගැනීමට උපකාරී වේ .AsEnumerable().

var results = from myRow in myDataTable.Rows.Cast<DataRow>() 
                  where myRow.Field<int>("RowNo") == 1 select myRow;

හෝ

var results = myDataTable.Rows.Cast<DataRow>()
                      .FirstOrDefault(x => x.Field<int>("RowNo") == 1);

අදහස් දැක්වීම්වල සඳහන් කර ඇති පරිදි, එය ලින්ක් ( යොමු ) හි කොටසක් බැවින් වෙනත් එක්රැස්වීම් අවශ්‍ය නොවේ.


5
System.Data.DataSetExtensions සඳහන් නොකර මෙය ක්‍රියාත්මක වේ.
user423430

29

ඩේටාසෙට් / ඩේටා ටේබල් හි දත්ත හැසිරවීමට ලින්ක් භාවිතා කිරීම

var results = from myRow in tblCurrentStock.AsEnumerable()
              where myRow.Field<string>("item_name").ToUpper().StartsWith(tbSearchItem.Text.ToUpper())
              select myRow;
DataView view = results.AsDataView();

1
AsDataView මා සඳහා Intellisense හි නොපෙන්වයි. මම System.Data.Linq සහ System.Linq භාවිතා කිරීම ඇතුළත් කළ නමුත් තවමත් එය ක්‍රියාත්මක නොවේ. ඔබ දන්නවාද මට නැති වී ඇත්තේ කුමක්ද? කලින්ම ස්තූතියි.
නයෝමි

A නාඕමි එය පැමිණේ System.Data.DataSetExtensions.
ලුවී වවේරු

29
//Create DataTable 
DataTable dt= new DataTable();
dt.Columns.AddRange(new DataColumn[]
{
   new DataColumn("ID",typeof(System.Int32)),
   new DataColumn("Name",typeof(System.String))

});

//Fill with data

dt.Rows.Add(new Object[]{1,"Test1"});
dt.Rows.Add(new Object[]{2,"Test2"});

//Now  Query DataTable with linq
//To work with linq it should required our source implement IEnumerable interface.
//But DataTable not Implement IEnumerable interface
//So we call DataTable Extension method  i.e AsEnumerable() this will return EnumerableRowCollection<DataRow>


// Now Query DataTable to find Row whoes ID=1

DataRow drow = dt.AsEnumerable().Where(p=>p.Field<Int32>(0)==1).FirstOrDefault();
 // 

23

මෙම සරල විමසුම් මාලාව උත්සාහ කරන්න:

var result=myDataTable.AsEnumerable().Where(myRow => myRow.Field<int>("RowNo") == 1);

4
විමසුම් සින්ටැක්ස් ” (පිළිගත් පිළිතුරේ) ට වඩා “ ක්‍රම දාමය ” (ඔබ මෙහි කර ඇති පරිදි) වඩා කැමති වන්නේ මෙය එක් පේළියකට ගැළපෙන සහ තවමත් කියවිය හැකි මූලික ස්ථානයක් වන බැවිනි. එක් එක් අයට.
මයික් ටීවී

16

පේළි එකතුවෙහි ඇති වස්තූන් සඳහා ඔබට LINQ භාවිතා කළ හැකිය:

var results = from myRow in myDataTable.Rows where myRow.Field("RowNo") == 1 select myRow;

1
DataTable.Rowsක්‍රියාත්මක නොවන නිසා IEnumerable, මෙම විමසුම සම්පාදනය කරන්නේ කෙසේදැයි මට නොපෙනේ.
onedaywhen

මෙය කිසියම් කේතයකින් සිදු කරන බව මා දුටු අතර එය සම්පාදනය කරයි. ඒ ඇයි දැයි දැන ගැනීමට උත්සාහ කිරීම.
BVernon

... හෝ ඔබට තෝරා ගැනීමේ ක්‍රමය තුළ පෙරහන් ප්‍රකාශනයක් භාවිතා කළ හැකිය: var results = myDataTable.Select ("RowNo = 1"); මෙය DataRow අරාවක් ලබා දෙයි.
ඉෂිකාවා

13

මෙය මා වෙනුවෙන් වැඩ කරන සහ ලැම්බඩා ප්‍රකාශන භාවිතා කරන සරල ක්‍රමයකි:

var results = myDataTable.Select("").FirstOrDefault(x => (int)x["RowNo"] == 1)

ඔබට විශේෂිත අගයක් අවශ්‍ය නම්:

if(results != null) 
    var foo = results["ColName"].ToString()


11

බොහෝ දුරට ඉඩ ඇති පරිදි, දත්තසෙට්, ඩේටා ටේබල් සහ ඩේටා රෝ සඳහා පන්ති දැනටමත් විසඳුමේ අර්ථ දක්වා ඇත. එය එසේ නම් ඔබට DataSetExtensions යොමු කිරීම අවශ්‍ය නොවේ.

උදා. DataSet පන්තියේ නම-> CustomSet, DataRow පන්තියේ නම-> CustomTableRow (අර්ථ දක්වා ඇති තීරු සමඟ: RowNo, ...)

var result = from myRow in myDataTable.Rows.OfType<CustomSet.CustomTableRow>()
             where myRow.RowNo == 1
             select myRow;

හෝ (මම කැමති පරිදි)

var result = myDataTable.Rows.OfType<CustomSet.CustomTableRow>().Where(myRow => myRow.RowNo);


8

පිළිතුරෙහි යෝජනා කර ඇති පරිදි ඩේටා ටේබල් සඳහා AsEnumerable () දිගුව සමඟ දත්ත කට්ටල වලට LINQ භාවිතා කිරීම ඉතා මන්දගාමී බව මගේ යෙදුමේදී මට පෙනී ගියේය. වේගය ප්‍රශස්තිකරණය කිරීමට ඔබ කැමති නම්, ජේම්ස් නිව්ටන්කින්ගේ Json.Net පුස්තකාලය භාවිතා කරන්න ( http://james.newtonking.com/json/help/index.html )

// Serialize the DataTable to a json string
string serializedTable = JsonConvert.SerializeObject(myDataTable);    
Jarray dataRows = Jarray.Parse(serializedTable);

// Run the LINQ query
List<JToken> results = (from row in dataRows
                    where (int) row["ans_key"] == 42
                    select row).ToList();

// If you need the results to be in a DataTable
string jsonResults = JsonConvert.SerializeObject(results);
DataTable resultsTable = JsonConvert.DeserializeObject<DataTable>(jsonResults);

සාමාන්‍යයෙන් මෙය වේගවත් යැයි මට සැකයි. එය අනුක්‍රමිකකරණ දෙකක පොදු කාර්යයක් ඇත, එක් ඩෙසරීකරණය සහ එක් විග්‍රහ කිරීමේ මෙහෙයුම්. කෙසේ වෙතත්, මම පහත් කොට සැලකුවේ එය සංක්ෂිප්ත නොවන නිසා ය, එනම් අනුක්‍රමිකකරණය / අභිමතකරණය ලැයිස්තුවක් පෙරීම එහි අභිප්‍රාය බව පැහැදිලි නොකරයි.
ක phu

@an phu, .AsEnumerable දිගු කිරීමේ ක්‍රමය භාවිතා කරමින් හෙවිවේට් System.Data.DataRowවස්තු එකතුවක් නිර්මාණය කරයි . අනුක්‍රමික හා විග්‍රහ කරන ලද දත්ත වගුව මඟින් එක් එක් පේළියේ තීරු නම් සහ අගයන්ගෙන් පමණක් සමන්විත සැහැල්ලු දත්ත නිර්මාණය කරයි. විමසුම ක්‍රියාත්මක වන විට, එය දත්ත මතකයට පටවනු ඇත, විශාල දත්ත කට්ටලයක් සඳහා හුවමාරුව ඇතුළත් විය හැකිය. සමහර විට, මෙහෙයුම් කිහිපයක පොදු කාර්යය මතකයේ සහ පිටත විශාල දත්ත ප්‍රමාණයක් පිටපත් කිරීමේ පොදු කාර්යයට වඩා අඩුය.
LandedGently

8

මෙය සපුරා ගන්නේ කෙසේද යන්න පිළිබඳ උදාහරණය පහත දැක්වේ:

DataSet dataSet = new DataSet(); //Create a dataset
dataSet = _DataEntryDataLayer.ReadResults(); //Call to the dataLayer to return the data

//LINQ query on a DataTable
var dataList = dataSet.Tables["DataTable"]
              .AsEnumerable()
              .Select(i => new
              {
                 ID = i["ID"],
                 Name = i["Name"]
               }).ToList();

7

VB.NET සඳහා කේතය මේ ආකාරයෙන් පෙනෙනු ඇත:

Dim results = From myRow In myDataTable  
Where myRow.Field(Of Int32)("RowNo") = 1 Select myRow

7
IEnumerable<string> result = from myRow in dataTableResult.AsEnumerable()
                             select myRow["server"].ToString() ;

6

මේක උත්සාහ කරන්න...

SqlCommand cmd = new SqlCommand( "Select * from Employee",con);
SqlDataReader dr = cmd.ExecuteReader( );
DataTable dt = new DataTable( "Employee" );
dt.Load( dr );
var Data = dt.AsEnumerable( );
var names = from emp in Data select emp.Field<String>( dt.Columns[1] );
foreach( var name in names )
{
    Console.WriteLine( name );
}

5

මේ වගේ ලින්ක් හරහා ඔබට එය අලංකාර ලෙස වැඩ කළ හැකිය:

from prod in TenMostExpensiveProducts().Tables[0].AsEnumerable()
where prod.Field<decimal>("UnitPrice") > 62.500M
select prod

හෝ ගතික ලින්ක් මෙන් මෙය (AsDynamic කෙලින්ම ඩේටාසෙට් ලෙස හැඳින්වේ):

TenMostExpensiveProducts().AsDynamic().Where (x => x.UnitPrice > 62.500M)

වඩාත්ම නම්‍යශීලී වන අතර අවසාන ප්‍රවේශයට මම කැමැත්තෙමි. PS: System.Data.DataSetExtensions.dllයොමු සම්බන්ධ කිරීමට අමතක නොකරන්න


5

ඔබට මෙය උත්සාහ කළ හැකිය, නමුත් එක් එක් තීරුව සඳහා වටිනාකම් වර්ගය ඔබට සහතික විය යුතුය

List<MyClass> result = myDataTable.AsEnumerable().Select(x=> new MyClass(){
     Property1 = (string)x.Field<string>("ColumnName1"),
     Property2 = (int)x.Field<int>("ColumnName2"),
     Property3 = (bool)x.Field<bool>("ColumnName3"),    
});

ලෝකය පිස්සු වැටී තිබේද? වර්ග අඩි වල වැරැද්ද කුමක්ද? DataRow [] drs = dt.Select ("id = 1"); සමහර විට මෙය පහසු නැත.
Programnik

0

මම පහත විසඳුම යෝජනා කරමි:

DataView view = new DataView(myDataTable); 
view.RowFilter = "RowNo = 1";
DataTable results = view.ToTable(true);

DataView ප්‍රලේඛනය දෙස බලන විට , අපට දැකිය හැකි පළමු දෙය මෙයයි:

වර්ග කිරීම, පෙරීම, සෙවීම, සංස්කරණය කිරීම සහ සංචලනය සඳහා දත්ත සමුදායක් පිළිබඳ දත්ත සමුදායක්, අභිරුචිකරණය කළ දර්ශනයක් නියෝජනය කරයි.

මෙයින් මට ලැබෙන්නේ ඩේටා ටේබල් යනු දත්ත ගබඩා කිරීම සඳහා පමණක් වන අතර ඩේටා වීව් අපට ඩේටා ටේබල්ට එරෙහිව "විමසීමට" හැකියාව ඇත.

මෙම විශේෂිත අවස්ථාවෙහිදී මෙය ක්‍රියාත්මක වන ආකාරය මෙන්න:

ඔබ SQL ප්‍රකාශය ක්‍රියාත්මක කිරීමට උත්සාහ කරයි

SELECT *
FROM myDataTable
WHERE RowNo = 1

"දත්ත ටේබල් භාෂාවෙන්". සී # හි අපි මේ ආකාරයට කියවමු:

FROM myDataTable
WHERE RowNo = 1
SELECT *

C # හි පෙනෙන ආකාරයට:

DataView view = new DataView(myDataTable);  //FROM myDataTable
view.RowFilter = "RowNo = 1";  //WHERE RowNo = 1
DataTable results = view.ToTable(true);  //SELECT *

0
                    //Json Formating code
                    //DT is DataTable
                    var filter = (from r1 in DT.AsEnumerable()

                                  //Grouping by multiple columns 
                                  group r1 by new
                                  {
                                      EMPID = r1.Field<string>("EMPID"),
                                      EMPNAME = r1.Field<string>("EMPNAME"),

                                  } into g
                                  //Selecting as new type
                                  select new
                                  {

                                      EMPID = g.Key.EMPID,
                                      MiddleName = g.Key.EMPNAME});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.