c# - 使用 Entity Framework 的最佳比较算法

标签 c# algorithm entity-framework asp.net-web-api

我想知道在创建历史记录和依赖项的同时比较已创建的多个对象并将对象的状态更改为非事件(已删除)的最佳方法是什么。

这也意味着我在关系表 (MarketCookies) 中比较过去和现在的对象。

Id     |    CookieID   |  MarketID  

我发现的丑陋解决方案是计算我更改了多少对象。
为此,让我们调用过去的项目:ListP
以及新项目:ListF

我把这个方法分为三个步骤:

1 - 计算两个列表;
2 - 找到 ListP 中不存在于 List F 中的对象,将它们的状态更改为 Inactive 并更新它们;
3 - 创建新对象并保存它们。

但是这段代码很难维护..我怎样才能编写一个简单的代码来维护并保持功能?

市场模式:

 public class Market()
 {
    public ICollection<Cookie> Cookies {get; set;}
 }

Cookie 模态:

 public class Cookie()
 {
   public int Id {get;set;}

   //Foreign Key
   public int CookieID {get;set}

   //Foreign Key
   public int MarketID {get;set;}
 }

代码:

  public void UpdateMarket (Market Market, int Id)
  {
     var ListP = MarketCookiesRepository.GetAll()
                 .Where(x => x.MarketID == Id && Market.State != "Inactive").ToList();
     var ListF = Market.Cookies.ToList();
     int ListPCount = ListP.Count();
     int ListFCount = ListF.Count();

     if(ListPCount > ListFCount)
     {
         ListP.Foreach(x => 
         {
            var ItemExists = ListF.Where(y => y.Id == x.Id).FirstOrDefault();

            if(ItemExists == null)
            {
               //Delete the Object
            }
         });

         ListF.Foreach(x => 
         {
            var ItemExists = ListP.Where(y => y.Id == x.Id).FirstOrDefault();

            if(ItemExists == null)
            {
               //Create Object
            }
         });
     }
     else if(ListPCount < ListFCount)
          {
              ListF.Foreach(x => 
              {
                 var ItemExists = ListP.Where(y => y.Id == x.Id).FirstOrDefault();

                 if(ItemExists == null)
                 {
                   //Create Objects
                 }
              });

              ListP.Foreach(x => 
              {
                 var ItemExists = ListF.Where(y => y.Id == x.Id).FirstOrDefault();

                 if(ItemExists == null)
                 {
                   //Delete Objects
                 }
              });
          }
          else if(ListPCount == ListFCount)
               {
                   ListP.Foreach(x => 
                   {
                        var ItemExists = ListF.Where(y => y.Id == x.Id).FirstOrDefault();

                        if(ItemExists == null)
                        {
                           //Delete Objects
                        }
                   });

                   ListF.Foreach(x => 
                   {
                       var ItemExists = ListP.Where(y => y.Id == x.Id).FirstOrDefault();

                        if(ItemExists == null)
                        {
                           //Create Objects
                        }
                   });
               }
  }

最佳答案

没有a good, minimal, complete code example这清楚地说明了这个问题,很难确定即使是一个好的实现会是什么样子,更不用说“最好的”了。但是,根据您的描述,它似乎是 LINQ Except()方法实际上可以很好地满足您的需求。例如:

public void UpdateMarket (Market Market, int Id)
{
    var ListP = MarketCookiesRepository.GetAll()
                .Where(x => x.MarketID == Id && Market.State != "Inactive").ToList();
    var ListF = Market.Cookies.ToList();

    foreach (var item in ListP.Except(ListF))
    {
        // set to inactive
    }

    foreach (var item in ListF.Except(ListP))
    {
        // create new object
    }
}

这当然假设您的对象已覆盖 Equals()GetHashCode() .如果没有,您可以提供自己的 IEqualityComparer<T> 实现对于上述。例如:

// General-purpose equality comparer implementation for convenience.
// Rather than declaring a new class for each time you want an
// IEqualityComparer<T>, just pass this class appropriate delegates
// to define the actual implementation desired.
class GeneralEqualityComparer<T> : IEqualityComparer<T>
{
    private readonly Func<T, T, bool> _equals;
    private readonly Func<T, int> _getHashCode;

    public GeneralEqualityComparer(Func<T, T, bool> equals, Func<T, int> getHashCode)
    {
        _equals = equals;
        _getHashCode = getHashCode;
    }

    public bool Equals(T t1, T t2)
    {
        return _equals(t1, t2);
    }

    public int GetHashCode(T t)
    {
        return _getHashCode(t);
    }
}

这样使用:

public void UpdateMarket (Market Market, int Id)
{
    var ListP = MarketCookiesRepository.GetAll()
                .Where(x => x.MarketID == Id && Market.State != "Inactive").ToList();
    var ListF = Market.Cookies.ToList();
    IEqualityComparer<Cookie> comparer = new GeneralEqualityComparer<Cookie>(
        (t1, t2) => t1.Id == t2.Id, t => t.Id.GetHashCode());

    foreach (var item in ListP.Except(ListF, comparer))
    {
        // set to inactive
    }

    foreach (var item in ListF.Except(ListP, comparer))
    {
        // create new object
    }
}

关于c# - 使用 Entity Framework 的最佳比较算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33158850/

相关文章:

entity-framework - linq to sql类和 Entity Framework 有什么区别

c# - 如何在 EF Code-First 中预编译 sql 查询?

c# - 在 C# 中创建一个空文件

c# - 使用 Lucene.NET 对 ASP.NET MVC View 的内容建立索引

algorithm - 使用 OCAML 进行函数式编程

algorithm - 我如何才能采用在 2D 空间中运行良好的算法并使其适应 3D 环境?

c# - 类型存在于 2 个程序集中(由于包依赖性)

c# - 如何创建一个在特定时间自动发送电子邮件的独立程序?

python - 识别 5 个 "forbidden"字符,这些字符导致*最少*从单词列表中排除

c# - 无法使用 ".Add()"插入新的 Entity Framework 实体