C# 在何处放置方法(实体或回购)

C# 在何处放置方法(实体或回购),c#,entity-framework,asp.net-mvc-3,oop,design-patterns,C#,Entity Framework,Asp.net Mvc 3,Oop,Design Patterns,我有两个EF生成的类 公共部分类管理 { 公共管理() { this.user=new HashSet(); } 公共int-id{get;set;}//PK //为简洁起见,省略了其他属性 公共虚拟ICollection用户{get;set;} } 及 公共部分类用户 { 公共字符串用户名{get;set;}//PK 公共字符串passwd{get;set;} public int admin_id{get;set;}//FK //为简洁起见,省略了其他属性 公共虚拟管理员{get;se

我有两个EF生成的类

公共部分类管理
{
公共管理()
{
this.user=new HashSet();
}
公共int-id{get;set;}//PK
//为简洁起见,省略了其他属性
公共虚拟ICollection用户{get;set;}
}

公共部分类用户
{  
公共字符串用户名{get;set;}//PK
公共字符串passwd{get;set;}
public int admin_id{get;set;}//FK
//为简洁起见,省略了其他属性
公共虚拟管理员{get;set;}
}
通过使用FK admin_id,用户属于管理员。如果admin_id和用户名相等,则该用户是管理员。示例:用户“梅西”、“内马尔”、“苏亚雷斯”和“123”都有管理员id 123。所以用户“123”是管理员。(可能不是最佳方法,但与问题无关。)

由于这两个类是EF自动生成的,将来可能会更改,因此我有另一个部分用户类,具有相同的名称空间,但位于不同的文件夹中(因此方法保留):

公共部分类用户
{
公共图书馆
{
返回admin_id.ToString().Equals(用户名);
}
}
我还有一个用户存储库:

公共类EFUserRepo:IUserRepo
{
私有实体上下文=新实体();
公共IQueryable用户{get{return context.user;}}
公共用户getUserByPK(字符串用户名)
{ 
返回context.user.Find(用户名);
}
公共用户deleteUser(字符串用户名){return null;}//尚未实现
public bool saveUser(user user){return false;}//尚未实现
}
我想用另一种方法获取给定用户的useradmin,如下所示:

public user getUserAdmin(string username){}//注意返回类型是user,不是admin!


我的问题是,我应该把这个方法放在哪里?
我可以这样把它放在EFUserRepo中:

public用户getUserAdmin(字符串用户名)
{
user=getUserByPK(用户名);
if(user==null)返回null;
返回context.user.Find(user.admin\u id);
}
公共用户getUserAdmin(用户用户)//与问题无关,但可能对其他人有深刻见解
{
返回getUserAdmin(user.username);
}
在我的控制器中称之为:

user adminUser=repo.getUserAdmin(loggedOnUser.username)//或者使用repo.getUserAdmin(loggedOnUser)获得相同的结果。
或者我可以把它放在部分用户类中,如下所示:

public用户getUserAdmin()
{
返回此.admin.user.Where(x=>x.isAdmin()).FirstOrDefault();
//由于数据库设置始终返回1个用户。
}
在我的控制器中称之为:

user adminUser=loggedOnUser.getUserAdmin();


我完全不知道什么是最好的方法。
如果我还想制作一种方法,比如:

public-admin-getAdmin(字符串用户名){}//注意这里的返回类型是admin,而不是user
然后我可以将其添加到我的用户存储库中:

public admin getAdmin(字符串用户名)
{
user=getUserByPK(用户名);
if(user==null)返回null;
返回user.admin;
//return context.admin.Find(user.admin_id);//也可以,但是从userrepo中访问admin集合是最佳实践吗
//返回新的EFAdminRepo().getAdminByPK(user.admin\u id)//也可以工作,但是非常难看
}
public admin getAdmin(user user)//同样,与问题无关,但可能对其他人有深刻的见解
{
返回getAdmin(user.username);
}
在我的控制器中称之为:

admin=repo.getAdmin(loggedOnUser.username)//或者使用repo.getAdmin(loggedOnUser)获得相同的结果。
或者我可以把它放在部分用户类中,如下所示:

public admin getAdmin()
{
返回此.admin.user.Where(x=>x.isAdmin()).First().admin;
}
在我的控制器中称之为:

admin admin=loggedOnUser.getAdmin();


真正的问题可能是,我是否使用

ObjectX obj=repo.methodforaccessingobjectx(entity.params);

ObjectX obj=entity.methodforaccessingobjectx();

根据您的解释(以及您使用ORM(如实体框架)的事实),保留EF对象的任何数据检索/修改功能是正确的。EF对象之所以被称为“模型”,是因为它们是模型,而且它们唯一要做的就是成为模型,并将数据库结构表示为POCO类

因此,将一些逻辑放在它们里面(更不用说您必须修改*.tt文件以使此逻辑持久,并且不会在每次模型更新时都松散)不是一个好主意。正如@Jenish已经说过的,保持模型结构尽可能简单

另一方面,您的回购协议应提供所有必要的数据访问方法,因此您必须在回购协议中使用此方法

更新1

所以关于你的下一个问题,关于在哪里放置以及如何获取用户管理员。我认为,如果您使用存储库模式,最好通过“主题”对其进行分解,这样您将拥有userrepo、adminrepo等等。然后,根据逻辑归属,一些方法将转到userrepo,一些转到adminrepo,等等

但通常,首先,您必须做出决定,是在前端使用DB模型,还是有单独的视图模型类仅用于视图渲染目的。若第一个是真的,我个人不认为有什么大不了的,若你们只是通过导航属性返回用户的管理员。在任何情况下,您都将DB模型类对象用作容器。因此,我认为直接将其作为用户类的导航属性返回,或者通过专用存储库方法返回,不会有任何显著的改变

另一方面,如果引入视图模型类并在视图模型db模型对象之间进行一些转换,则
public admin getAdmin(string username)
{
    user user = getUserByPK(username);
    if (user == null) return null;
    return user.admin;
    //return context.admin.Find(user.admin_id);//Also works, but is it best practise to access the admin collection from within the userrepo, think not
    //return new EFAdminRepo().getAdminByPK(user.admin_id)//Also works, but seams really ugly
}