Identifying duplicate datatable rows using LINQ
up vote
0
down vote
favorite
I have an app where the user inputs search terms which are used to query a database and return matching rows. I'd like to find the rows that are duplicated like this:
File Tool Product Time1 MeasureTime Row
319 S32 AX 11/13 1:12AM 11/13 5:02am 5
318 S32 AX 11/13 1:12AM 11/13 4:41am 5
In these cases the entry with the higher file ID may be an errant re-measurement so I'd like to be able to highlight this to the user.
I have this code that counts if there are duplicate rows:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
}).Select(g => new {
Tool = g.Key.Tool,
Product = g.Key.Product,
Time1 = g.Key.Time1,
Row = g.Key.Row,
Count = g.Count() }).ToList();
This returns a generic list that I'd like to be able to take the count from and add it back to the initial datatable db2. Then when a user selects a row where the count is greater than 1 I can alert the user. I would like to only alert when the user picks the higher file number so I may need to do this with a ranking, but either way, how can I take what I have and add it back to the original table?
c# linq datatable
|
show 1 more comment
up vote
0
down vote
favorite
I have an app where the user inputs search terms which are used to query a database and return matching rows. I'd like to find the rows that are duplicated like this:
File Tool Product Time1 MeasureTime Row
319 S32 AX 11/13 1:12AM 11/13 5:02am 5
318 S32 AX 11/13 1:12AM 11/13 4:41am 5
In these cases the entry with the higher file ID may be an errant re-measurement so I'd like to be able to highlight this to the user.
I have this code that counts if there are duplicate rows:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
}).Select(g => new {
Tool = g.Key.Tool,
Product = g.Key.Product,
Time1 = g.Key.Time1,
Row = g.Key.Row,
Count = g.Count() }).ToList();
This returns a generic list that I'd like to be able to take the count from and add it back to the initial datatable db2. Then when a user selects a row where the count is greater than 1 I can alert the user. I would like to only alert when the user picks the higher file number so I may need to do this with a ranking, but either way, how can I take what I have and add it back to the original table?
c# linq datatable
What makes the rows duplicate? Just the tool and product names?
– Abion47
Nov 13 at 17:34
Tool, product, time1 (time off the tool), and row.
– ejyoung
Nov 13 at 17:43
I'm confused, why would you "add it back" to the original table, isn't it already there?
– MikeH
Nov 13 at 18:04
I want to add the count (or rank) back to the initial table so that when the user selects a row I can identify potential problems. At the moment when the user selects a row to open I am not looking to see if it matches tool/product/time/row as another row.
– ejyoung
Nov 13 at 18:13
Do you need to be connected back to the initial table for operations performed by the user? What happens after selecting a row?
– NetMage
Nov 13 at 20:30
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have an app where the user inputs search terms which are used to query a database and return matching rows. I'd like to find the rows that are duplicated like this:
File Tool Product Time1 MeasureTime Row
319 S32 AX 11/13 1:12AM 11/13 5:02am 5
318 S32 AX 11/13 1:12AM 11/13 4:41am 5
In these cases the entry with the higher file ID may be an errant re-measurement so I'd like to be able to highlight this to the user.
I have this code that counts if there are duplicate rows:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
}).Select(g => new {
Tool = g.Key.Tool,
Product = g.Key.Product,
Time1 = g.Key.Time1,
Row = g.Key.Row,
Count = g.Count() }).ToList();
This returns a generic list that I'd like to be able to take the count from and add it back to the initial datatable db2. Then when a user selects a row where the count is greater than 1 I can alert the user. I would like to only alert when the user picks the higher file number so I may need to do this with a ranking, but either way, how can I take what I have and add it back to the original table?
c# linq datatable
I have an app where the user inputs search terms which are used to query a database and return matching rows. I'd like to find the rows that are duplicated like this:
File Tool Product Time1 MeasureTime Row
319 S32 AX 11/13 1:12AM 11/13 5:02am 5
318 S32 AX 11/13 1:12AM 11/13 4:41am 5
In these cases the entry with the higher file ID may be an errant re-measurement so I'd like to be able to highlight this to the user.
I have this code that counts if there are duplicate rows:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
}).Select(g => new {
Tool = g.Key.Tool,
Product = g.Key.Product,
Time1 = g.Key.Time1,
Row = g.Key.Row,
Count = g.Count() }).ToList();
This returns a generic list that I'd like to be able to take the count from and add it back to the initial datatable db2. Then when a user selects a row where the count is greater than 1 I can alert the user. I would like to only alert when the user picks the higher file number so I may need to do this with a ranking, but either way, how can I take what I have and add it back to the original table?
c# linq datatable
c# linq datatable
asked Nov 13 at 17:31
ejyoung
225
225
What makes the rows duplicate? Just the tool and product names?
– Abion47
Nov 13 at 17:34
Tool, product, time1 (time off the tool), and row.
– ejyoung
Nov 13 at 17:43
I'm confused, why would you "add it back" to the original table, isn't it already there?
– MikeH
Nov 13 at 18:04
I want to add the count (or rank) back to the initial table so that when the user selects a row I can identify potential problems. At the moment when the user selects a row to open I am not looking to see if it matches tool/product/time/row as another row.
– ejyoung
Nov 13 at 18:13
Do you need to be connected back to the initial table for operations performed by the user? What happens after selecting a row?
– NetMage
Nov 13 at 20:30
|
show 1 more comment
What makes the rows duplicate? Just the tool and product names?
– Abion47
Nov 13 at 17:34
Tool, product, time1 (time off the tool), and row.
– ejyoung
Nov 13 at 17:43
I'm confused, why would you "add it back" to the original table, isn't it already there?
– MikeH
Nov 13 at 18:04
I want to add the count (or rank) back to the initial table so that when the user selects a row I can identify potential problems. At the moment when the user selects a row to open I am not looking to see if it matches tool/product/time/row as another row.
– ejyoung
Nov 13 at 18:13
Do you need to be connected back to the initial table for operations performed by the user? What happens after selecting a row?
– NetMage
Nov 13 at 20:30
What makes the rows duplicate? Just the tool and product names?
– Abion47
Nov 13 at 17:34
What makes the rows duplicate? Just the tool and product names?
– Abion47
Nov 13 at 17:34
Tool, product, time1 (time off the tool), and row.
– ejyoung
Nov 13 at 17:43
Tool, product, time1 (time off the tool), and row.
– ejyoung
Nov 13 at 17:43
I'm confused, why would you "add it back" to the original table, isn't it already there?
– MikeH
Nov 13 at 18:04
I'm confused, why would you "add it back" to the original table, isn't it already there?
– MikeH
Nov 13 at 18:04
I want to add the count (or rank) back to the initial table so that when the user selects a row I can identify potential problems. At the moment when the user selects a row to open I am not looking to see if it matches tool/product/time/row as another row.
– ejyoung
Nov 13 at 18:13
I want to add the count (or rank) back to the initial table so that when the user selects a row I can identify potential problems. At the moment when the user selects a row to open I am not looking to see if it matches tool/product/time/row as another row.
– ejyoung
Nov 13 at 18:13
Do you need to be connected back to the initial table for operations performed by the user? What happens after selecting a row?
– NetMage
Nov 13 at 20:30
Do you need to be connected back to the initial table for operations performed by the user? What happens after selecting a row?
– NetMage
Nov 13 at 20:30
|
show 1 more comment
2 Answers
2
active
oldest
votes
up vote
0
down vote
As written above you'll need to create a new list because you've lost the references to the original data:
var updateList = db2.Where(r=> Tool = r.Field<string>("Tool")
&& Product = r.Field<string>("Product")
&& Time1 = r.Field<DateTime>("Time1")
&& Row = r.Field<Int32>("Row"));
foreach (var ul in updateList)
ul.Count = updateList.Count();
Alternatively, if you remove the Select
from your code you can retain references to the original data:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
});
foreach (var d in duplicates) //Iterate through the groups
{
foreach (var item in d) //Iterate through the items in a group
{
item.Count = d.Count();
}
}
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
Do you have twoforeach
statements? That error means you're still working with anIEnumerable
of some sort, which has the methodCount()
.
– MikeH
Nov 13 at 19:33
Yes I have bothforeach
statements just like you showed in your answer. Hmm...
– ejyoung
Nov 13 at 19:39
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (Count = g.Count()
)
– MikeH
Nov 13 at 19:43
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
|
show 1 more comment
up vote
0
down vote
Apparently you designed that you can identify a measurement by the values of Tool
, Product
, etc: if you've got two items with same values of Tool
, Product
, etc, they belong to the same measurement group, and might even be the same measurement.
To prevent that I have to say "same Tool, Product, etc" over and over again, I call the collection of these properties the MeasurementId
. So whenever I say MeasurementId
, I mean the properties Tool/Product/Timel/Row
Problem description
If you've got two measurements with the same MeasurementId
, it might be that they are re-measurements. Therefore, whenever the operator selects a measurement of which there are others with the same MeasurementId
, you want to warn the operator, maybe not if the operator selects the oldest measurement.
Your problem seems to be similar as keeping several versions of something in a database. If someone adds a new item with the same ``MeasurementId. but with a different
File, it is as if you add a new
Version` of the measurement to your database.
You want to warn the operator if he doesn't select the oldest version.
You chose the following solution:
I'd like to be able to take the count from and add it back to the initial datatable db2
Instead of adding the count, to your table, consider adding the Id of the "previous version", and if there is no previous version, add 0.
class Measurement
{
public int Id {get; set;}
public int File {get; set;}
// measurement identification
public string Tool {get; set;}
public string Product {get; set;}
...
// you wanted to add a Count, instead add a previous version
public int PreviousMeasurementId {get; set;} // 0 if no previous measurement
}
Before you add a measurement check if there is already a similar measurement:
void AddMeasurement(Measurement measurementToAdd)
{
var lastMeasurementVersionId = dbContext.Measurements
.Where( measurement => // select with same measurementId:
measurement.Tool == measurementToAdd.Tool
&& measurement.Product == measurementToAdd.Product
&& ...)
// from the remaining versions, keep the one with the highest File:
.OrderByDescending(measurement => measurement.File)
// I'm only interested in the Id of this measurement
.Select(measurement => measurement.Id)
.FirstOrDefault();
Now if there were already similar measurements, lastMeasurementVersionId is the Id of the last similar measurement. If there were none, this value equals 0.
Add the new measurement after assigning lastMeasurementVersionId to PreviouseMeasurementId
:
measurementToAdd.PreviousMeasurementId = lastMeasurementVersionId;
dbContext.Measurements.Add(measurementToAdd);
dbContext.SaveChanges();
}
How will this help me with my problem?
If the operator selects a Measurement
, the only thing you'll have to do is check the value of PreviousMeasurementId
. If it is zero, the operator selected the first measurement, if not, you can warn the operator that there are several versions of this measurement. The selected one might be a re-measurements.
Possible improvements:
- Consider adding an extra index for your composite
MeasurementId
. The values of aMeasurementId
won't change often, but the query to fetch all measurement with thisMeasurementId
is much faster - If you are not interested in all versions, but really only in the first version, don't remember the
PreviousMeasurementId
, but remember theFirstMeasurementId
.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
As written above you'll need to create a new list because you've lost the references to the original data:
var updateList = db2.Where(r=> Tool = r.Field<string>("Tool")
&& Product = r.Field<string>("Product")
&& Time1 = r.Field<DateTime>("Time1")
&& Row = r.Field<Int32>("Row"));
foreach (var ul in updateList)
ul.Count = updateList.Count();
Alternatively, if you remove the Select
from your code you can retain references to the original data:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
});
foreach (var d in duplicates) //Iterate through the groups
{
foreach (var item in d) //Iterate through the items in a group
{
item.Count = d.Count();
}
}
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
Do you have twoforeach
statements? That error means you're still working with anIEnumerable
of some sort, which has the methodCount()
.
– MikeH
Nov 13 at 19:33
Yes I have bothforeach
statements just like you showed in your answer. Hmm...
– ejyoung
Nov 13 at 19:39
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (Count = g.Count()
)
– MikeH
Nov 13 at 19:43
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
|
show 1 more comment
up vote
0
down vote
As written above you'll need to create a new list because you've lost the references to the original data:
var updateList = db2.Where(r=> Tool = r.Field<string>("Tool")
&& Product = r.Field<string>("Product")
&& Time1 = r.Field<DateTime>("Time1")
&& Row = r.Field<Int32>("Row"));
foreach (var ul in updateList)
ul.Count = updateList.Count();
Alternatively, if you remove the Select
from your code you can retain references to the original data:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
});
foreach (var d in duplicates) //Iterate through the groups
{
foreach (var item in d) //Iterate through the items in a group
{
item.Count = d.Count();
}
}
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
Do you have twoforeach
statements? That error means you're still working with anIEnumerable
of some sort, which has the methodCount()
.
– MikeH
Nov 13 at 19:33
Yes I have bothforeach
statements just like you showed in your answer. Hmm...
– ejyoung
Nov 13 at 19:39
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (Count = g.Count()
)
– MikeH
Nov 13 at 19:43
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
|
show 1 more comment
up vote
0
down vote
up vote
0
down vote
As written above you'll need to create a new list because you've lost the references to the original data:
var updateList = db2.Where(r=> Tool = r.Field<string>("Tool")
&& Product = r.Field<string>("Product")
&& Time1 = r.Field<DateTime>("Time1")
&& Row = r.Field<Int32>("Row"));
foreach (var ul in updateList)
ul.Count = updateList.Count();
Alternatively, if you remove the Select
from your code you can retain references to the original data:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
});
foreach (var d in duplicates) //Iterate through the groups
{
foreach (var item in d) //Iterate through the items in a group
{
item.Count = d.Count();
}
}
As written above you'll need to create a new list because you've lost the references to the original data:
var updateList = db2.Where(r=> Tool = r.Field<string>("Tool")
&& Product = r.Field<string>("Product")
&& Time1 = r.Field<DateTime>("Time1")
&& Row = r.Field<Int32>("Row"));
foreach (var ul in updateList)
ul.Count = updateList.Count();
Alternatively, if you remove the Select
from your code you can retain references to the original data:
var duplicates = db2.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Product = r.Field<string>("Product"),
Time1 = r.Field<DateTime>("Time1"),
Row = r.Field<Int32>("Row")
});
foreach (var d in duplicates) //Iterate through the groups
{
foreach (var item in d) //Iterate through the items in a group
{
item.Count = d.Count();
}
}
edited Nov 13 at 19:34
answered Nov 13 at 18:38
MikeH
3,075925
3,075925
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
Do you have twoforeach
statements? That error means you're still working with anIEnumerable
of some sort, which has the methodCount()
.
– MikeH
Nov 13 at 19:33
Yes I have bothforeach
statements just like you showed in your answer. Hmm...
– ejyoung
Nov 13 at 19:39
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (Count = g.Count()
)
– MikeH
Nov 13 at 19:43
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
|
show 1 more comment
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
Do you have twoforeach
statements? That error means you're still working with anIEnumerable
of some sort, which has the methodCount()
.
– MikeH
Nov 13 at 19:33
Yes I have bothforeach
statements just like you showed in your answer. Hmm...
– ejyoung
Nov 13 at 19:39
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (Count = g.Count()
)
– MikeH
Nov 13 at 19:43
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
I'm trying the second method there and I am getting an error of "Cannot assign to 'Count' because it is a 'method group'". Do I need to declare it somewhere first? Thanks for the help!
– ejyoung
Nov 13 at 19:28
Do you have two
foreach
statements? That error means you're still working with an IEnumerable
of some sort, which has the method Count()
.– MikeH
Nov 13 at 19:33
Do you have two
foreach
statements? That error means you're still working with an IEnumerable
of some sort, which has the method Count()
.– MikeH
Nov 13 at 19:33
Yes I have both
foreach
statements just like you showed in your answer. Hmm...– ejyoung
Nov 13 at 19:39
Yes I have both
foreach
statements just like you showed in your answer. Hmm...– ejyoung
Nov 13 at 19:39
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (
Count = g.Count()
)– MikeH
Nov 13 at 19:43
I think I misunderstood the error. Yes, you will need a field in your class to assign that value to. I assumed you already had one since it was in your question (
Count = g.Count()
)– MikeH
Nov 13 at 19:43
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
Yeah, i was creating the count as part of the select statement which works but I was looking for a way to get that count back to my original datatable so I can use the count going forward.
– ejyoung
Nov 13 at 20:03
|
show 1 more comment
up vote
0
down vote
Apparently you designed that you can identify a measurement by the values of Tool
, Product
, etc: if you've got two items with same values of Tool
, Product
, etc, they belong to the same measurement group, and might even be the same measurement.
To prevent that I have to say "same Tool, Product, etc" over and over again, I call the collection of these properties the MeasurementId
. So whenever I say MeasurementId
, I mean the properties Tool/Product/Timel/Row
Problem description
If you've got two measurements with the same MeasurementId
, it might be that they are re-measurements. Therefore, whenever the operator selects a measurement of which there are others with the same MeasurementId
, you want to warn the operator, maybe not if the operator selects the oldest measurement.
Your problem seems to be similar as keeping several versions of something in a database. If someone adds a new item with the same ``MeasurementId. but with a different
File, it is as if you add a new
Version` of the measurement to your database.
You want to warn the operator if he doesn't select the oldest version.
You chose the following solution:
I'd like to be able to take the count from and add it back to the initial datatable db2
Instead of adding the count, to your table, consider adding the Id of the "previous version", and if there is no previous version, add 0.
class Measurement
{
public int Id {get; set;}
public int File {get; set;}
// measurement identification
public string Tool {get; set;}
public string Product {get; set;}
...
// you wanted to add a Count, instead add a previous version
public int PreviousMeasurementId {get; set;} // 0 if no previous measurement
}
Before you add a measurement check if there is already a similar measurement:
void AddMeasurement(Measurement measurementToAdd)
{
var lastMeasurementVersionId = dbContext.Measurements
.Where( measurement => // select with same measurementId:
measurement.Tool == measurementToAdd.Tool
&& measurement.Product == measurementToAdd.Product
&& ...)
// from the remaining versions, keep the one with the highest File:
.OrderByDescending(measurement => measurement.File)
// I'm only interested in the Id of this measurement
.Select(measurement => measurement.Id)
.FirstOrDefault();
Now if there were already similar measurements, lastMeasurementVersionId is the Id of the last similar measurement. If there were none, this value equals 0.
Add the new measurement after assigning lastMeasurementVersionId to PreviouseMeasurementId
:
measurementToAdd.PreviousMeasurementId = lastMeasurementVersionId;
dbContext.Measurements.Add(measurementToAdd);
dbContext.SaveChanges();
}
How will this help me with my problem?
If the operator selects a Measurement
, the only thing you'll have to do is check the value of PreviousMeasurementId
. If it is zero, the operator selected the first measurement, if not, you can warn the operator that there are several versions of this measurement. The selected one might be a re-measurements.
Possible improvements:
- Consider adding an extra index for your composite
MeasurementId
. The values of aMeasurementId
won't change often, but the query to fetch all measurement with thisMeasurementId
is much faster - If you are not interested in all versions, but really only in the first version, don't remember the
PreviousMeasurementId
, but remember theFirstMeasurementId
.
add a comment |
up vote
0
down vote
Apparently you designed that you can identify a measurement by the values of Tool
, Product
, etc: if you've got two items with same values of Tool
, Product
, etc, they belong to the same measurement group, and might even be the same measurement.
To prevent that I have to say "same Tool, Product, etc" over and over again, I call the collection of these properties the MeasurementId
. So whenever I say MeasurementId
, I mean the properties Tool/Product/Timel/Row
Problem description
If you've got two measurements with the same MeasurementId
, it might be that they are re-measurements. Therefore, whenever the operator selects a measurement of which there are others with the same MeasurementId
, you want to warn the operator, maybe not if the operator selects the oldest measurement.
Your problem seems to be similar as keeping several versions of something in a database. If someone adds a new item with the same ``MeasurementId. but with a different
File, it is as if you add a new
Version` of the measurement to your database.
You want to warn the operator if he doesn't select the oldest version.
You chose the following solution:
I'd like to be able to take the count from and add it back to the initial datatable db2
Instead of adding the count, to your table, consider adding the Id of the "previous version", and if there is no previous version, add 0.
class Measurement
{
public int Id {get; set;}
public int File {get; set;}
// measurement identification
public string Tool {get; set;}
public string Product {get; set;}
...
// you wanted to add a Count, instead add a previous version
public int PreviousMeasurementId {get; set;} // 0 if no previous measurement
}
Before you add a measurement check if there is already a similar measurement:
void AddMeasurement(Measurement measurementToAdd)
{
var lastMeasurementVersionId = dbContext.Measurements
.Where( measurement => // select with same measurementId:
measurement.Tool == measurementToAdd.Tool
&& measurement.Product == measurementToAdd.Product
&& ...)
// from the remaining versions, keep the one with the highest File:
.OrderByDescending(measurement => measurement.File)
// I'm only interested in the Id of this measurement
.Select(measurement => measurement.Id)
.FirstOrDefault();
Now if there were already similar measurements, lastMeasurementVersionId is the Id of the last similar measurement. If there were none, this value equals 0.
Add the new measurement after assigning lastMeasurementVersionId to PreviouseMeasurementId
:
measurementToAdd.PreviousMeasurementId = lastMeasurementVersionId;
dbContext.Measurements.Add(measurementToAdd);
dbContext.SaveChanges();
}
How will this help me with my problem?
If the operator selects a Measurement
, the only thing you'll have to do is check the value of PreviousMeasurementId
. If it is zero, the operator selected the first measurement, if not, you can warn the operator that there are several versions of this measurement. The selected one might be a re-measurements.
Possible improvements:
- Consider adding an extra index for your composite
MeasurementId
. The values of aMeasurementId
won't change often, but the query to fetch all measurement with thisMeasurementId
is much faster - If you are not interested in all versions, but really only in the first version, don't remember the
PreviousMeasurementId
, but remember theFirstMeasurementId
.
add a comment |
up vote
0
down vote
up vote
0
down vote
Apparently you designed that you can identify a measurement by the values of Tool
, Product
, etc: if you've got two items with same values of Tool
, Product
, etc, they belong to the same measurement group, and might even be the same measurement.
To prevent that I have to say "same Tool, Product, etc" over and over again, I call the collection of these properties the MeasurementId
. So whenever I say MeasurementId
, I mean the properties Tool/Product/Timel/Row
Problem description
If you've got two measurements with the same MeasurementId
, it might be that they are re-measurements. Therefore, whenever the operator selects a measurement of which there are others with the same MeasurementId
, you want to warn the operator, maybe not if the operator selects the oldest measurement.
Your problem seems to be similar as keeping several versions of something in a database. If someone adds a new item with the same ``MeasurementId. but with a different
File, it is as if you add a new
Version` of the measurement to your database.
You want to warn the operator if he doesn't select the oldest version.
You chose the following solution:
I'd like to be able to take the count from and add it back to the initial datatable db2
Instead of adding the count, to your table, consider adding the Id of the "previous version", and if there is no previous version, add 0.
class Measurement
{
public int Id {get; set;}
public int File {get; set;}
// measurement identification
public string Tool {get; set;}
public string Product {get; set;}
...
// you wanted to add a Count, instead add a previous version
public int PreviousMeasurementId {get; set;} // 0 if no previous measurement
}
Before you add a measurement check if there is already a similar measurement:
void AddMeasurement(Measurement measurementToAdd)
{
var lastMeasurementVersionId = dbContext.Measurements
.Where( measurement => // select with same measurementId:
measurement.Tool == measurementToAdd.Tool
&& measurement.Product == measurementToAdd.Product
&& ...)
// from the remaining versions, keep the one with the highest File:
.OrderByDescending(measurement => measurement.File)
// I'm only interested in the Id of this measurement
.Select(measurement => measurement.Id)
.FirstOrDefault();
Now if there were already similar measurements, lastMeasurementVersionId is the Id of the last similar measurement. If there were none, this value equals 0.
Add the new measurement after assigning lastMeasurementVersionId to PreviouseMeasurementId
:
measurementToAdd.PreviousMeasurementId = lastMeasurementVersionId;
dbContext.Measurements.Add(measurementToAdd);
dbContext.SaveChanges();
}
How will this help me with my problem?
If the operator selects a Measurement
, the only thing you'll have to do is check the value of PreviousMeasurementId
. If it is zero, the operator selected the first measurement, if not, you can warn the operator that there are several versions of this measurement. The selected one might be a re-measurements.
Possible improvements:
- Consider adding an extra index for your composite
MeasurementId
. The values of aMeasurementId
won't change often, but the query to fetch all measurement with thisMeasurementId
is much faster - If you are not interested in all versions, but really only in the first version, don't remember the
PreviousMeasurementId
, but remember theFirstMeasurementId
.
Apparently you designed that you can identify a measurement by the values of Tool
, Product
, etc: if you've got two items with same values of Tool
, Product
, etc, they belong to the same measurement group, and might even be the same measurement.
To prevent that I have to say "same Tool, Product, etc" over and over again, I call the collection of these properties the MeasurementId
. So whenever I say MeasurementId
, I mean the properties Tool/Product/Timel/Row
Problem description
If you've got two measurements with the same MeasurementId
, it might be that they are re-measurements. Therefore, whenever the operator selects a measurement of which there are others with the same MeasurementId
, you want to warn the operator, maybe not if the operator selects the oldest measurement.
Your problem seems to be similar as keeping several versions of something in a database. If someone adds a new item with the same ``MeasurementId. but with a different
File, it is as if you add a new
Version` of the measurement to your database.
You want to warn the operator if he doesn't select the oldest version.
You chose the following solution:
I'd like to be able to take the count from and add it back to the initial datatable db2
Instead of adding the count, to your table, consider adding the Id of the "previous version", and if there is no previous version, add 0.
class Measurement
{
public int Id {get; set;}
public int File {get; set;}
// measurement identification
public string Tool {get; set;}
public string Product {get; set;}
...
// you wanted to add a Count, instead add a previous version
public int PreviousMeasurementId {get; set;} // 0 if no previous measurement
}
Before you add a measurement check if there is already a similar measurement:
void AddMeasurement(Measurement measurementToAdd)
{
var lastMeasurementVersionId = dbContext.Measurements
.Where( measurement => // select with same measurementId:
measurement.Tool == measurementToAdd.Tool
&& measurement.Product == measurementToAdd.Product
&& ...)
// from the remaining versions, keep the one with the highest File:
.OrderByDescending(measurement => measurement.File)
// I'm only interested in the Id of this measurement
.Select(measurement => measurement.Id)
.FirstOrDefault();
Now if there were already similar measurements, lastMeasurementVersionId is the Id of the last similar measurement. If there were none, this value equals 0.
Add the new measurement after assigning lastMeasurementVersionId to PreviouseMeasurementId
:
measurementToAdd.PreviousMeasurementId = lastMeasurementVersionId;
dbContext.Measurements.Add(measurementToAdd);
dbContext.SaveChanges();
}
How will this help me with my problem?
If the operator selects a Measurement
, the only thing you'll have to do is check the value of PreviousMeasurementId
. If it is zero, the operator selected the first measurement, if not, you can warn the operator that there are several versions of this measurement. The selected one might be a re-measurements.
Possible improvements:
- Consider adding an extra index for your composite
MeasurementId
. The values of aMeasurementId
won't change often, but the query to fetch all measurement with thisMeasurementId
is much faster - If you are not interested in all versions, but really only in the first version, don't remember the
PreviousMeasurementId
, but remember theFirstMeasurementId
.
answered Nov 15 at 10:05
Harald Coppoolse
11k12958
11k12958
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53286566%2fidentifying-duplicate-datatable-rows-using-linq%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What makes the rows duplicate? Just the tool and product names?
– Abion47
Nov 13 at 17:34
Tool, product, time1 (time off the tool), and row.
– ejyoung
Nov 13 at 17:43
I'm confused, why would you "add it back" to the original table, isn't it already there?
– MikeH
Nov 13 at 18:04
I want to add the count (or rank) back to the initial table so that when the user selects a row I can identify potential problems. At the moment when the user selects a row to open I am not looking to see if it matches tool/product/time/row as another row.
– ejyoung
Nov 13 at 18:13
Do you need to be connected back to the initial table for operations performed by the user? What happens after selecting a row?
– NetMage
Nov 13 at 20:30