【问题标题】:Generically find any items where item property value is equal using LINQ使用 LINQ 通常查找项目属性值相等的任何项目
【发布时间】:2016-12-09 21:10:47
【问题描述】:

我正在尝试实现一个通用存储库模式,该模式在 IEnumerable 中实现通用项目的 CRUD 操作。我遇到了一般查找可能已经在 IEnumerable 中的项目的问题。我需要以编程方式传递构成“键”或不同记录的属性,然后使用 LINQ 对定义的属性执行 Enumerable.Any(),以便查看该对象是否已存在于 IEnumberable 中。到目前为止,这是我的代码。

    //Generic Method
    public void AddItem(TEntity item)
    {
        var entities = GetAllItems().ToList(); //Method gets cached IEnumerable<TEntity>

        if(true)//Generically see if TEntity is already in the list based of defined properties
        {
            entities.Add(item);
        }

    }

    //Same function but non-generic
    private void AddItem(MyObject object)
    {
        var objects = GetAllItems().ToList(); //Method gets cached IEnumerable<MyObject>

        if(!objects.Any(a=> a.ID == MyObject.ID ))
        {
            objects.Add(object);
            _cache.AddReplaceCache(objects);
        }

    }

注意:键可以是对象 MyObject 上的任何一个或多个属性

【问题讨论】:

  • 似乎这应该是在此之上执行的检查。我只是让重复密钥问题在数据库级别失败,因为它不应该进入存储库。再说一次,我不会使用通用存储库。

标签: c# linq generics reflection


【解决方案1】:

您可以让您的实体从一个通用接口继承:

public interface IEntity
{
    int ID { get; set; }
}

然后你可以重新定义你的方法

public void AddItem<TEntity>(TEntity entity) where TEntity : IEntity
{
    // Now you can access entity.ID
}

现在,如果您不总是想通过 ID 进行比较,那么您可以在您的方法中添加一个谓词:

public void AddItem<TEntity>(TEntity entity, Func<TEntity, bool> predicate)
{
    var objects = GetAllItems().ToList();

    // You might need some logic in the predicate to check for null
    if(!objects.Any(a => predicate(a as TEntity))
    {
        objects.Add(entity);
        _cache.AddReplaceCache(objects);
    }

}

然后你会使用你的函数作为

repository.AddItem(entity, e => e.ID == entity.ID && e.OtherProperty == entity.OtherProperty);

【讨论】:

  • 像魅力一样工作!谢谢!
【解决方案2】:

如果我对您的理解正确,您的问题是TEntity 没有属性ID。因此,让您的实体继承具有例如 ID 列的通用接口。

public interface IObject
{
    int ID {get; set;}

    //define all other properties which are shared between your Entities.
}
public class MyObject : IObject
{
    public int ID {get; set;}

    //other properties.
}

public void AddItem(TEntity item): where TEntity:IObject
{
    var entities = GetAllItems().ToList(); //Method gets cached IEnumerable<TEntity>

    if(!objects.Any(a=> a.ID == item.ID ))//Generically see if TEntity is already in the list based of defined properties
    {
        entities.Add(item);
    }

}

【讨论】:

  • 据我了解,每个实体都可以有一个由多个字段组成的复合键,这些字段将被传入并用于检查重复项。
  • @stephen.vakil 他在谈论一些“关键”,但我只是重新编写他的代码以使用泛型。如果他有由多个字段组成的键,他需要在界面中定义它们,然后获取数据。流程应该是一样的
猜你喜欢
  • 2013-02-23
  • 2015-12-27
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多