Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.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# 为什么Automapper和NHibernate会导致N+;1._C#_Nhibernate_Automapper - Fatal编程技术网

C# 为什么Automapper和NHibernate会导致N+;1.

C# 为什么Automapper和NHibernate会导致N+;1.,c#,nhibernate,automapper,C#,Nhibernate,Automapper,我使用NHibernate创建了此查询: public IList<Category> GetCategoriesByUsername(string username) { Category cAlias = null; User uAlias = null; Keyword kAlias = null; var categories = SessionFactory.GetCurrentSession().QueryOver<Category

我使用NHibernate创建了此查询:

public IList<Category> GetCategoriesByUsername(string username)
{
    Category cAlias = null;
    User uAlias = null;
    Keyword kAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .JoinAlias(() => cAlias.User, () => uAlias)
    .Where(() => uAlias.Username == username)
    .Future<Category>();

    var keywords = SessionFactory.GetCurrentSession().QueryOver<Keyword>(() => kAlias)
    .JoinAlias(c => c.Category, () => cAlias)
    .Where(() => cAlias.Id == kAlias.Category.Id)
    .Future<Keyword>();

    IList<Category> list = (List<Category>)categories.ToList();

    return list;
}
public IList GetCategoriesByUsername(字符串用户名)
{
类别cAlias=null;
User=null;
关键词kAlias=null;
var categories=SessionFactory.GetCurrentSession().QueryOver(()=>cAlias)
.JoinAlias(()=>cAlias.User,()=>uAlias)
.Where(()=>uAlias.Username==用户名)
.Future();
var关键字=SessionFactory.GetCurrentSession().QueryOver(()=>kAlias)
.JoinAlias(c=>c.Category,()=>cAlias)
.Where(()=>cAlias.Id==kAlias.Category.Id)
.Future();
IList list=(list)categories.ToList();
退货清单;
}
这很好,给了我一个类别列表,其中每个类别都有自己的关键字。在我的服务层中,我尝试将其转换为带有Automapper的ViewModel,它可以正常工作,但不符合预期。它为类别列表中的每个关键字创建一个新查询(N+1)。它不会在列表中的每个类别中使用已填充的关键字

以下是我的模型和ViewModels:

public class Category
{
    public virtual Id { get; set; }
    public virtual string Name { get; set; }
    public virtual ICollection<Keyword> Keywords { get; set; }
    public virtual User User { get; set; }
}

public class CategoryView
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<KeywordSummaryView> Keywords { get; set; }
}

public class Keyword
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual Category Category { get; set; }
}

public class KeywordSummaryView
{
    public int Id { get; set; }
    public string Name { get; set; }
}
公共类类别
{
公共虚拟Id{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟ICollection关键字{get;set;}
公共虚拟用户用户{get;set;}
}
公共类类别视图
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共IList关键字{get;set;}
}
公共类关键字
{
公共虚拟整数Id{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟字符串描述{get;set;}
公共虚拟类别{get;set;}
}
公共类关键字摘要视图
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
我的映射:

public class AutoMapperBootStrapper
{
    public static void ConfigureAutoMapper()
    {
        Mapper.CreateMap<Category, CategoryView>();
        Mapper.CreateMap<Keyword, KeywordSummaryView>();
    }
}

public static class CategoryMap
{
    public static IList<CategoryView> ConvertToCategoryView(this IList<Category> category)
    {
        return Mapper.Map<IList<Category>, IList<CategoryView>>(category);
    }
}
公共类自动映射引导程序
{
公共静态无效配置自动映射()
{
CreateMap();
CreateMap();
}
}
公共静态类类别映射
{
公共静态IList ConvertToCategoryView(此IList类别)
{
返回Mapper.Map(类别);
}
}
从模型到视图模型:

IList<Category> categories = _categoryRepository.GetCategoriesByUsername(request.Username);

response.Categories = categories.ConvertToCategoryView();
IList categories=\u categoryRepository.GetCategoriesByUsername(request.Username);
response.Categories=Categories.converttocategoriview();

它不使用列表中每个类别中已填充的关键字,而是为每个关键字(N+1)创建一个新查询。有什么地方我做错了吗?

我想这两个都应该阻止N+1选择

public IList<Category> GetCategoriesByUsername(string username)
{
    User uAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .Fetch(x => x.Keywords ).Eager
    .JoinAlias(() => cAlias.User, () => uAlias)
    .Where(() => uAlias.Username == username);
    .TransformUsing(Transformers.DistinctRootEntity)
    .List<Category>();

    return categories ;
}


public IList<Category> GetCategoriesByUsername(string username)
{
    User uAlias = null;
    Keyword kAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .JoinAlias(() => cAlias.User, () => uAlias)
    .JoinAlias(x => x.Keywords , () => kAlias, JoinType.LeftOuterJoin)
    .Where(() => uAlias.Username == username);
    .TransformUsing(Transformers.DistinctRootEntity)
    .List<Category>();

    return categories;
}
public IList GetCategoriesByUsername(字符串用户名)
{
User=null;
var categories=SessionFactory.GetCurrentSession().QueryOver(()=>cAlias)
.Fetch(x=>x.Keywords)
.JoinAlias(()=>cAlias.User,()=>uAlias)
。其中(()=>uAlias.Username==用户名);
.变压器使用(变压器.距离)
.List();
退货类别;
}
公共IList GetCategoriesByUsername(字符串用户名)
{
User=null;
关键词kAlias=null;
var categories=SessionFactory.GetCurrentSession().QueryOver(()=>cAlias)
.JoinAlias(()=>cAlias.User,()=>uAlias)
.JoinAlias(x=>x.Keywords,()=>kAlias,JoinType.LeftOuterJoin)
。其中(()=>uAlias.Username==用户名);
.变压器使用(变压器.距离)
.List();
退货类别;
}

希望这会有所帮助

我想这两种方法都会阻止N+1选择

public IList<Category> GetCategoriesByUsername(string username)
{
    User uAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .Fetch(x => x.Keywords ).Eager
    .JoinAlias(() => cAlias.User, () => uAlias)
    .Where(() => uAlias.Username == username);
    .TransformUsing(Transformers.DistinctRootEntity)
    .List<Category>();

    return categories ;
}


public IList<Category> GetCategoriesByUsername(string username)
{
    User uAlias = null;
    Keyword kAlias = null;

    var categories = SessionFactory.GetCurrentSession().QueryOver<Category>(() => cAlias)
    .JoinAlias(() => cAlias.User, () => uAlias)
    .JoinAlias(x => x.Keywords , () => kAlias, JoinType.LeftOuterJoin)
    .Where(() => uAlias.Username == username);
    .TransformUsing(Transformers.DistinctRootEntity)
    .List<Category>();

    return categories;
}
public IList GetCategoriesByUsername(字符串用户名)
{
User=null;
var categories=SessionFactory.GetCurrentSession().QueryOver(()=>cAlias)
.Fetch(x=>x.Keywords)
.JoinAlias(()=>cAlias.User,()=>uAlias)
。其中(()=>uAlias.Username==用户名);
.变压器使用(变压器.距离)
.List();
退货类别;
}
公共IList GetCategoriesByUsername(字符串用户名)
{
User=null;
关键词kAlias=null;
var categories=SessionFactory.GetCurrentSession().QueryOver(()=>cAlias)
.JoinAlias(()=>cAlias.User,()=>uAlias)
.JoinAlias(x=>x.Keywords,()=>kAlias,JoinType.LeftOuterJoin)
。其中(()=>uAlias.Username==用户名);
.变压器使用(变压器.距离)
.List();
退货类别;
}

希望这会有所帮助

到目前为止,我还没有机会在NHibernate中使用
Futures
,所以我不会去寻找答案,但是当使用
QueryOver
API时,您可以始终添加
Fetch(x=>x.Keywords)。渴望
以确保在
类别
中急切加载
关键字
集合,并避免N+1。只是一个想法。:)这不会在列表中给我重复的结果吗?
Fetch.Eager
部分只表示应该急切地获取集合/相关项目。没有更多,也没有更少,所以如果
关键字中有重复项,它们仍然会存在;)我的意思是,举例来说,如果我在一个类别中有三个关键字,那么该类别将被复制三次。到目前为止,我还没有机会在NHibernate中使用
Futures
,所以我不会去寻找答案,但是当使用
QueryOver
API时,您可以始终添加
Fetch(x=>x.keywords).Eager
以确保在
类别
中急切加载
关键字
集合,并避免N+1。只是一个想法。:)这不会在列表中给我重复的结果吗?
Fetch.Eager
部分只表示应该急切地获取集合/相关项目。没有更多,也没有更少,所以如果
关键字中有重复项,它们仍然会存在;)我的意思是,如果我在一个类别中有三个关键字,那么该类别将重复三次。谢谢你的回答。这确实给了我一个查询,但如果我在一个类别中有三个关键字,我会得到三个重复的类别。这可以通过DistincTrotentyResultTransformer解决,但我认为这不是一个很好的解决方案。@Mr.nuub yep,I