PDA

View Full Version : بدست آوردن اختلاف دو datatable



S_VB.max
دوشنبه 26 فروردین 1392, 08:17 صبح
سلام
من دو تا datatable دارم که می خوام تفاوت این دو تا را با استفاده از Linq و بدون استفاده از For به دست بیاورم
البته از دستور زیر هم استفاده کردم ولی جواب نگرفتم


var qry1 = from db1 in ds1.Tables[0].AsEnumerable()
select db1;
var qry2 = from db1 in ds.Tables[0].AsEnumerable()
select db1;
var exceptAB = qry1.Except(qry2).CopyToDataTable(); ;


نتیجه نهایی باید چیزی مثل این باشه :

Datatable DT1
A

1
2
3




Datatable DT2
A

1
2


Result
A
3

کسی می تونه به من کمک کنه چجوری اختلاف دو DataTable را بدست بیارم؟

massar
دوشنبه 26 فروردین 1392, 08:57 صبح
سلام
کدتون هیچ وقت جواب نمیده چون except دیتا رو ها رو مقایسه میکنه نه قادیر داخلوشونو، برای اینکار از کد زیر استفاده کنید:


d2.AsEnumerable().Except(d1.AsEnumerable(),System. Data.DataRowComparer.Default);

S_VB.max
دوشنبه 26 فروردین 1392, 09:10 صبح
کد شما را تو برنامه امتحان کردم ولی نتیجه نهایی اختلاف دو datatable نیست (نتیجه همون چیزی میشه که با کد خودم بدست میاد)
ممنون میشم راهنمایی کنید

massar
دوشنبه 26 فروردین 1392, 09:18 صبح
اگه جواب نمیده خودتو مقایسه گر رو بنویسید:


class DataRowComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow x, DataRow y)
{
//agar hardo null bodand barabarand
if (x == null && y == null)
return true;
//hatman hardo null nistan pas age ykishun
//null bashe unyeki null nist pas nabarabarand
if (x == null || y == null)
return false;

//agar tedade selola baham barabar nabod hatman do row nabarabarand
if (x.ItemArray.Length != y.ItemArray.Length)
return false;

for (int i = 0; i < x.ItemArray.Length; i++)
{
//agar inja maghadir e x v y ro b onvane object estefade konim
//momkene javab nagirim
if (x[i].ToString() != y[i].ToString())
return false;
}

return true;
}

public int GetHashCode(DataRow obj)
{
throw new NotImplementedException();
}
}

S_VB.max
دوشنبه 26 فروردین 1392, 09:53 صبح
ممنون دوست عزیز این کد جواب میده
ولی چجوری این کارو با Linq و بدون استفاده از دستور for انجام بدم ؟

massar
دوشنبه 26 فروردین 1392, 11:26 صبح
var q = d1.AsEnumerable()
.Select((DataRow r) => new { Id = (int)r[0], Name = r[1].ToString(), Age = (int)r[2] })
.Except(d2.AsEnumerable()
.Select((DataRow r) => new { Id = (int)r[0], Name = r[1].ToString(), Age = (int)r[2] }));

S_VB.max
سه شنبه 27 فروردین 1392, 11:14 صبح
بلاخره راه حلش را پیدا کردم اینم کدش:

var dt2Cola = new HashSet<int>(DT2 .AsEnumerable()
.Select(x => x.Field<int>("A")));

var q = DT1 .AsEnumerable()
.Where(x => !dt2Cola.Contains(x.Field<int>("A")));

FastCode
سه شنبه 27 فروردین 1392, 14:32 عصر
بلاخره راه حلش را پیدا کردم اینم کدش:

var dt2Cola = new HashSet<int>(DT2 .AsEnumerable()
.Select(x => x.Field<int>("A")));

var q = DT1 .AsEnumerable()
.Where(x => !dt2Cola.Contains(x.Field<int>("A")));

یعنی حاضرید سرعت رو به زیر یک درصد برسونید ولی دو تا حلقه ننویسید؟ آدم این روزها یه چیزایی میبینه.
حداقل با SQL مینوشتید که ترافیکتون زیاد نشه.
یا اطلاعات رو سمت سرور hash میکردید و سمت کلاینت از اون hash استفاده میکردید(نه hashset ای که کلی CPU میگیره)
یا اطلاعات هر سطر رو میریختید توی یک کلاس و با هم مقایسه میکردید(اگر روش اول رو کنار بزارید این سریعترین روش هست چون میتونید در زمان خوندن اطلاعات سطر های تکراری رو حذف کنید.)