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?










share|improve this question






















  • 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















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?










share|improve this question






















  • 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













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?










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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


















  • 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












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();
}
}





share|improve this answer























  • 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










  • 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










  • 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


















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 differentFile, it is as if you add a newVersion` 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 a MeasurementId won't change often, but the query to fetch all measurement with this MeasurementId 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 the FirstMeasurementId.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    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

























    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();
    }
    }





    share|improve this answer























    • 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










    • 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










    • 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















    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();
    }
    }





    share|improve this answer























    • 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










    • 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










    • 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













    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();
    }
    }





    share|improve this answer














    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();
    }
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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










    • 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










    • 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










    • 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












    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 differentFile, it is as if you add a newVersion` 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 a MeasurementId won't change often, but the query to fetch all measurement with this MeasurementId 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 the FirstMeasurementId.






    share|improve this answer

























      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 differentFile, it is as if you add a newVersion` 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 a MeasurementId won't change often, but the query to fetch all measurement with this MeasurementId 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 the FirstMeasurementId.






      share|improve this answer























        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 differentFile, it is as if you add a newVersion` 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 a MeasurementId won't change often, but the query to fetch all measurement with this MeasurementId 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 the FirstMeasurementId.






        share|improve this answer












        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 differentFile, it is as if you add a newVersion` 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 a MeasurementId won't change often, but the query to fetch all measurement with this MeasurementId 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 the FirstMeasurementId.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 15 at 10:05









        Harald Coppoolse

        11k12958




        11k12958






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            How to change which sound is reproduced for terminal bell?

            Can I use Tabulator js library in my java Spring + Thymeleaf project?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents