Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有可能在一个地方推广这段代码吗?_C# - Fatal编程技术网

C# 有可能在一个地方推广这段代码吗?

C# 有可能在一个地方推广这段代码吗?,c#,C#,我有以下型号: public class Customer { public int Id {get; set;} public int GroupId {get; set;} public int Number {get; set;} public string Name {get; set;} } 我的所有域模型都包含GroupId属性。为用户分配了GroupId,当用户创建实体时,其GroupId将与实体一起保存。用户只能对具有其GroupId的实体执行C

我有以下型号:

public class Customer
{
    public int Id {get; set;}
    public int GroupId {get; set;}
    public int Number {get; set;}
    public string Name {get; set;}
}
我的所有域模型都包含
GroupId
属性。为用户分配了
GroupId
,当用户创建实体时,其
GroupId
将与实体一起保存。用户只能对具有其
GroupId
的实体执行CRUD操作

因此,目前,在我的服务层,基于
PredicateBuilder
扩展,我有一个方法,在加载实体时添加
GroupId

public Customer Get(Expression<Func<Customer, bool>> where)
{
    var addGroup = groupRepository.Get(EntityType.Customer).AddGroup;
    if (addGroup)
        where = where.And(x => x.GroupId == user.GroupId);

    return customerRepository.Get(where);
}
公共客户获取(表达式where)
{
var addGroup=groupRepository.Get(EntityType.Customer).addGroup;
如果(添加组)
其中=where.And(x=>x.GroupId==user.GroupId);
返回customerRepository.Get(在何处);
}
每个
Get
方法都执行上述操作


有没有办法将上述代码集中在一个地方,而不必在我所有服务的每个
Get
方法中重复代码?

您可以提取接口

public interface IGroup
{
 int GroupId {get; set;}
}
然后更新您的方法以使用该接口:

public IGroup Get(Expression<Func<IGroup, bool>> where)
{
    var addGroup = groupRepository.Get(EntityType.Customer).AddGroup;
    if (addGroup)
        where = where.And(x => x.GroupId == user.GroupId);

    return customerRepository.Get(where);
}
我的所有域模型都包含GroupId属性

然后,您的所有域模型都应该实现一个定义
GroupId
属性的接口(我们称之为
IHasGroup

然后,分解代码应该很容易:

public Customer Get(Expression<Func<Customer, bool>> where)
{
    return GetHelper(EntityType.Customer, where, customerRepository.Get);
}

public static T GetHelper<T>(EntityType type, Expression<Func<T, bool>> where, 
                             Func<Expression<Func<T, bool>>, T> repositoryAccessor) 
    where T : IHasGroup
{
    var addGroup = groupRepository.Get(type).AddGroup;
    if (addGroup)
        where = where.And(x => x.GroupId == user.GroupId);

    return repositoryAccessor(where);
}
公共客户获取(表达式where)
{
返回GetHelper(EntityType.Customer,其中,customerRepository.Get);
}
公共静态T GetHelper(EntityType类型,表达式,其中,
Func repositoryAccessor)
其中T:IHasGroup
{
var addGroup=groupRepository.Get(type).addGroup;
如果(添加组)
其中=where.And(x=>x.GroupId==user.GroupId);
返回存储存取器(其中);
}

将customerRepository封装在用户特定的customerRepository中,如

public class UserSpecificCustomerRepository : ICustomerRepository{
 private User _user;
 private ICustomerRepository _customerRepository;

 public UserSpecificCustomerRepository(User user, ICustomerRepository repo){
   _user = user;
   _customerRepository = repo;
 }

 public Customer Get(Expression<Func<Customer, bool>> where){
   where = where.And(x => x.GroupId == _user.GroupId);

  _customerRepository.Get(where);
 }
}
公共类UserSpecificCustomerRepository:ICCustomerRepository{
私人用户(u User),;
专用ICCustomerRepository\u customerRepository;
公共用户特定CustomerRepository(用户用户,ICCustomerRepository repo){
_用户=用户;
_customerRepository=回购;
}
公共客户获取(表达式where){
其中=where.And(x=>x.GroupId==\u user.GroupId);
_customerRepository.Get(在何处);
}
}
现在只有一个地方可以扩展表达式。您的代码将更改为

public Customer Get(Expression<Func<Customer, bool>> where)
{
  var addGroup = groupRepository.Get(EntityType.Customer).AddGroup;
  if (addGroup) {
    return new UserSpecificCustomerRepository(user, customerRepository).Get(where);
  }

  return customerRepository.Get(where);
}
公共客户获取(表达式where)
{
var addGroup=groupRepository.Get(EntityType.Customer).addGroup;
如果(添加组){
返回新的UserSpecificCustomerRepository(用户,customerRepository).Get(其中);
}
返回customerRepository.Get(在何处);
}

尝试使用baseEntity,并在其基础上使用一些常用方法 然后在所有实体中继承baseEntity,这样每个实体都有通用方法

public class EntityBase<T>
{
    public virtual T Get(Expression<Func<T, bool>> where)
    {
        //your Logic here
    }

    public virtual IEnumerable<T> GetAll()
    {
      //Your Logic here
    }

    public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
    {
        //Your Logic here
    }
}
公共类EntityBase
{
公共虚拟T Get(表达式,其中)
{
//你的逻辑在这里
}
公共虚拟IEnumerable GetAll()
{
//你的逻辑在这里
}
公共虚拟IEnumerable GetMany(表达式,其中)
{
//你的逻辑在这里
}
}

希望这能对您有所帮助。

他们能从基本实体继承吗?@Sayse只有在EF Code First允许TPH的情况下才能在上述情况下使用。恐怕我对Code First或TPH的了解不够,无法知道答案(如果EF Code First允许的话)。。。我的想法是使用泛型基类。。。我遇到以下异常:
无法将类型“Customer”强制转换为类型“IHasGroup”。LINQ to实体仅支持强制转换EDM基元或枚举类型。
Ok解决了它。刚刚添加了
约束,效果很好。这是一个常见问题。如果使用接口,则无法在Linq查询中使用,因为实体框架不知道此属性。如果您想这样做,您需要让您的所有实体从同一个基本实体继承,这很可能是一个大禁忌。。。
public class EntityBase<T>
{
    public virtual T Get(Expression<Func<T, bool>> where)
    {
        //your Logic here
    }

    public virtual IEnumerable<T> GetAll()
    {
      //Your Logic here
    }

    public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
    {
        //Your Logic here
    }
}