将多个Func表达式传递给C#方法

时间:2018-02-07 10:53:18

标签: c# .net entity-framework generics

实体框架的DbEntityEntry有一个方法 Collection ,它接受lambda表达式来加载实体。

DbCollectionEntry<TEntity, TElement> Collection<TElement>(Expression<Func<TEntity, ICollection<TElement>>> navigationProperty) where TElement : class;

在我的项目中,我们遵循存储库模式,所以为了调用它,我在存储库中创建了一个接受与参数相同的方法。

 TModel GetItem<TElement>(object[] id, Expression<Func<TModel, object>> navigationProperty = null,
        Expression<Func<TModel, ICollection<TElement>>> navigationCollection = null, string collectionEntity = "")
        where TElement : class;

从业务逻辑层我将该方法调用为

 var model = _repository.GetItem(
                    new object[]
                    {
                        viewModel.Id
                    },
                    navigationCollection: x => x.ProductSubVersions,
                    collectionEntity: nameof(ProductStatusSubSystem.SubSystem));

其中x是为BusinessManager和存储库定义的模型

public class ProductStatus : BaseModel
{
    public ProductStatus()
    {
        // ReSharper disable once DoNotCallOverridableMethodsInConstructor
        ProductSubVersions = new List<ProductStatusSubSystem>();
    }

    /// <summary>
    /// Name of the product
    /// </summary>
    [Required, MaxLength(100)]
    public string Name { get; set; }


    /// <summary>
    /// product version validity start date
    /// </summary>
    public DateTime ValidFrom { get; set; }

    /// <summary>
    /// product version valid till
    /// </summary>
    public DateTime? ValidTill { get; set; }

    /// <summary>
    /// This field used to keep track of history of a product
    /// </summary>
    public int ProductNumber { get; set; }

    public bool DefaultProduct { get; set; }

    /// <summary>
    /// all versions of this product
    /// </summary>
    public virtual List<ProductStatusSubSystem> ProductSubVersions { get; set; }

    /// <summary>
    /// all fallback languages attached to this language
    /// </summary>
    public virtual List<ProductStatusLanguage> ProductStatusLanguages { get; set; }


}

业务经理

public class BaseBusinessManager<ProductStatus, ProductStatusViewModel>, IProductStatusBusinessManager
{
}


 public class VersionBaseBusinessManager<TModel, TViewModel> : IVersionBaseBusinessManager<TModel, TViewModel>
    where TModel : class, new()
    where TViewModel : class, new()
{

    private readonly ICrudRepository<TModel> _repository;
}

但现在我有一个奇怪的要求,我需要从实体加载一个以上的集合属性(我也想加载ProductStatusLanguages)。如何使用多种类型的TElement定义表达式&lt; Func&lt; TEntity,ICollection&lt; TElement&gt;&gt;&gt; 的列表?

这是存储库方法

public virtual TModel GetItem<TElement>(object[] id, Expression<Func<TModel, object>> navigationProperty = null, Expression<Func<TModel, ICollection<TElement>>> navigationCollection = null, string collectionEntity = "")
        where TElement : class
    {
        var entity = Table.Find(id);
        if (navigationProperty != null)
        {
            DatabaseContext.Entry(entity).Reference(navigationProperty).Load();
        }
        if (navigationCollection != null)
        {
            DatabaseContext.Entry(entity).Collection(navigationCollection).Load();
            if (!string.IsNullOrWhiteSpace(collectionEntity))
            {
                DatabaseContext.Entry(entity)
               .Collection(navigationCollection)
               .Query()
               .Include(collectionEntity).Load();
            }
        }

P.S:在阅读Ivan Stoev的评论后,我写了一个方法,它接受表达式作为参数并加载集合

public virtual void LoadCollection<TElement>(TModel entity,
        Expression<Func<TModel, ICollection<TElement>>> navigationCollection, string collectionEntity = "") where TElement : class
    {
        if (entity == null)
            return;
        DatabaseContext.Entry(entity).Collection(navigationCollection).Load();
        if (!string.IsNullOrWhiteSpace(collectionEntity))
        {
            DatabaseContext.Entry(entity)
           .Collection(navigationCollection)
           .Query()
           .Include(collectionEntity).Load();
        }
    }

0 个答案:

没有答案