Identifying duplicate datatable rows using LINQ












0















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 '18 at 17:34











  • Tool, product, time1 (time off the tool), and row.

    – ejyoung
    Nov 13 '18 at 17:43











  • I'm confused, why would you "add it back" to the original table, isn't it already there?

    – MikeH
    Nov 13 '18 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 '18 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 '18 at 20:30
















0















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 '18 at 17:34











  • Tool, product, time1 (time off the tool), and row.

    – ejyoung
    Nov 13 '18 at 17:43











  • I'm confused, why would you "add it back" to the original table, isn't it already there?

    – MikeH
    Nov 13 '18 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 '18 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 '18 at 20:30














0












0








0








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 '18 at 17:31









ejyoungejyoung

225




225













  • What makes the rows duplicate? Just the tool and product names?

    – Abion47
    Nov 13 '18 at 17:34











  • Tool, product, time1 (time off the tool), and row.

    – ejyoung
    Nov 13 '18 at 17:43











  • I'm confused, why would you "add it back" to the original table, isn't it already there?

    – MikeH
    Nov 13 '18 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 '18 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 '18 at 20:30



















  • What makes the rows duplicate? Just the tool and product names?

    – Abion47
    Nov 13 '18 at 17:34











  • Tool, product, time1 (time off the tool), and row.

    – ejyoung
    Nov 13 '18 at 17:43











  • I'm confused, why would you "add it back" to the original table, isn't it already there?

    – MikeH
    Nov 13 '18 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 '18 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 '18 at 20:30

















What makes the rows duplicate? Just the tool and product names?

– Abion47
Nov 13 '18 at 17:34





What makes the rows duplicate? Just the tool and product names?

– Abion47
Nov 13 '18 at 17:34













Tool, product, time1 (time off the tool), and row.

– ejyoung
Nov 13 '18 at 17:43





Tool, product, time1 (time off the tool), and row.

– ejyoung
Nov 13 '18 at 17:43













I'm confused, why would you "add it back" to the original table, isn't it already there?

– MikeH
Nov 13 '18 at 18:04





I'm confused, why would you "add it back" to the original table, isn't it already there?

– MikeH
Nov 13 '18 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 '18 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 '18 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 '18 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 '18 at 20:30












2 Answers
2






active

oldest

votes


















0














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 '18 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 '18 at 19:33











  • Yes I have both foreach statements just like you showed in your answer. Hmm...

    – ejyoung
    Nov 13 '18 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 '18 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 '18 at 20:03



















0














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',
    autoActivateHeartbeat: false,
    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









    0














    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 '18 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 '18 at 19:33











    • Yes I have both foreach statements just like you showed in your answer. Hmm...

      – ejyoung
      Nov 13 '18 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 '18 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 '18 at 20:03
















    0














    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 '18 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 '18 at 19:33











    • Yes I have both foreach statements just like you showed in your answer. Hmm...

      – ejyoung
      Nov 13 '18 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 '18 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 '18 at 20:03














    0












    0








    0







    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 '18 at 19:34

























    answered Nov 13 '18 at 18:38









    MikeHMikeH

    3,258927




    3,258927













    • 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 '18 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 '18 at 19:33











    • Yes I have both foreach statements just like you showed in your answer. Hmm...

      – ejyoung
      Nov 13 '18 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 '18 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 '18 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 '18 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 '18 at 19:33











    • Yes I have both foreach statements just like you showed in your answer. Hmm...

      – ejyoung
      Nov 13 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 19:33













    Yes I have both foreach statements just like you showed in your answer. Hmm...

    – ejyoung
    Nov 13 '18 at 19:39





    Yes I have both foreach statements just like you showed in your answer. Hmm...

    – ejyoung
    Nov 13 '18 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 '18 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 '18 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 '18 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 '18 at 20:03













    0














    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




























      0














      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


























        0












        0








        0







        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 '18 at 10:05









        Harald CoppoolseHarald Coppoolse

        11.7k12959




        11.7k12959






























            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.




            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

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python