属性筛选


  在前面 插入实体更新实体 时特别说明过,使用 new 一个对象进行插入或更新时,会造成一些非空字段,如 int、long、DateTime 等等数据的误更新,所以不建议使用这种方法。现在你可以使用属性过滤器,将不必要的属性过滤掉,这样就不会产生失误了。

  属性过滤器 PropertyFilter 分为包含策略和排除策略两种。包含策略是指只插入或更新你指定的属性,而排队策略则是排除你所指定的属性。你可以在 EntityRepository<T> 实例上使用 IncludeFilter 方法指定所需要包含的属性,或使用 ExcludeFilter 方法指定需要排除的属性。

  支持属性过滤的方法有以下这些:

  • Insert(entity) / InsertAsync(entity)
[TestMethod]
public void TestInserWithFilter()
{
    using (var db = new DbContext())
    {
        var order = new Orders();
        order.ShipName = "fireasy";
        order.CustomerID = "";
        
        db.Orders
          //仅插入 CustomerID 和 ShipName
          .IncludeFilter(s => s.With(nameof(Orders.CustomerID)).With(t => t.ShipName))
          .Insert(order);
    }
}
  • Update(entity) / UpdateAsync(entity)
[TestMethod]
public void TestUpdateWithFilter()
{
    using (var db = new DbContext())
    {
        var order = new Orders { OrderID = 11092 };
        order.ShipName = "fireasy";

        db.Orders
          .ExcludeFilter(s => s.With(t => t.Freight)) //不更新 Freight
          .Update(order);
    }
}
  • Update(entity, expression) / UpdateAsync(entity, expression)
[TestMethod]
public void TestUpdateWithFilter()
{
    using (var db = new DbContext())
    {
        var order = new Orders { Freight = 1, OrderDate = DateTime.Now };
        db.Orders.IncludeFilter(s => s.With(t => t.Freight))
            .Update(order, s => s.OrderDate >= DateTime.Now);
    }
}
  • Batch(entities) / BatchAsync(entities)
[TestMethod]
public void TestBatchWithFilter()
{
    using (var db = new DbContext())
    {
        var list = new List<Products>();

        for (var i = 0; i < 10; i++)
        {
            var product = db.New<Products>();
            product.ProductName = "aa" + i;
            product.Discontinued = 0;
            list.Add(product);
        }

        db.Products.IncludeFilter(s => s.With(t => t.ProductName)
            .Batch(list, (u, s) => u.Insert(s));
    }
}

  它还可以接受一个匿名构造函数表达式,如下所示:

[TestMethod]
public void TestUpdateWithNewExpFilter()
{
    using (var db = new DbContext())
    {
        var order = new Orders { Freight = 1, OrderDate = DateTime.Now };
        
        //方法一
        db.Orders.IncludeFilter(t => new { t.Freight, t.OrderDate })
            .Update(order, s => s.OrderDate >= DateTime.Now);
        
        //方法二
        db.Orders.IncludeFilter(s => s.With(t => new { t.Freight, t.OrderDate }))
            .Update(order, s => s.OrderDate >= DateTime.Now);
    }
}

  PropertyFilter<T> 是一个抽象类,你可以自己去实现 Filter 方法的过滤规则,然后使用 EntityRepository<T> 的 Filter 方法来添加它过滤属性。如下所示:

[TestMethod]
public void TestCustmeFilter()
{
    using (var db = new DbContext())
    {
        var order = new Orders { OrderID = 11092 };
        order.ShipName = "fireasy";

        var filter = new MyPropertyFilter<Orders>().With(t => t.ShipName);

        db.Orders.Filter(filter).Insert(order);
    }
}

public class MyPropertyFilter<TEntity> : PropertyFilter<TEntity>
{
    public override bool Filter(IProperty property)
    {
        return base.Properties.Contains(property.Name);
    }
}