如何使用nhibernate获取具有外键引用的第二个表(财务)中不存在的第一个表(项目)中的记录

时间:2013-02-25 11:56:54

标签: nhibernate fluent-nhibernate

我正在尝试查询nhibernate和MSSQL中的简单数据结构

dbo.Projects :Id(int,not null)

dbo.Finances :Id(int,not null),ProjectId(int,not null),对dbo.projects的外键引用

我想获取项目表中的所有记录,这些记录在财务表中没有,其中财务表具有外键引用ProjectId。 我正在从EntityFramework迁移到(流利)Nhibernate 3?

    //So far I have got here: 
    public IQueryable<ProjectModel> GetProjectsNotPresentInFinance()
    {
        var factory = Fluently.Configure()
            .Database(MsSqlConfiguration
                .MsSql2008
                    .ConnectionString(m_connectionString))
            .Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<ProjectMap>()                   
               ).BuildSessionFactory();

        using (var session = factory.OpenSession())
        {
            var allprojects = session.QueryOver<ProjectModel>();
            var projectsToReturn = allprojects.List<ProjectModel>().AsQueryable();

       //---    Something like : all the records not in finances table ---------
       // .Where( proj => !db.Finances.Where(fin => fin.ProjectId == proj.Id).Any())
       // .Select(project => new ProjectModel
       // {
       //     Id=project.Id,
       //     ProjectName = project.ProjectName,                 
       // });

            return projectsToReturn;
        }            

    }



public class FinanceModel
{
    public virtual int Id { get; set; }
    public virtual int ProjectId { get; set; }       
}

public class ProjectModel
{
    public virtual int Id { get; set; }
    public virtual string ProjectName { get; set; }
}

public class ProjectMap:ClassMap<ProjectModel>
{
    public ProjectMap() {
        Table("Projects");
        Id(x => x.Id);
        Map(x => x.ProjectName);
    }
}

public class FinanceMap : ClassMap<FinanceModel>
{
    public FinanceMap()
    {
        Table("Finances");
        Id(x => x.Id);
        References(x => x.ProjectModel);
    }
}

    //-------------------------------------------------------
    //This is an Equivalent working code Using EntityFramework :
    public IQueryable<ProjectModel> GetProjectsNotPresentInFinance() {
        IQueryable<ProjectModel> projectList = db.Projects
        .Where( proj => !db.Finances.Where(fin => fin.ProjectId == proj.Id).Any())
        .Select(project => new ProjectModel
        {
            Id=project.Id,
            ProjectName = project.ProjectName,                 
        });
        return projectList;
    }
    //-------------------------------------------------------

1 个答案:

答案 0 :(得分:1)

第二个想法,你可以尝试这个,而不用使用子查询改变你的映射:

var notOrphanProjectIdsSubquery = QueryOver.Of<FinanceModel>()
                                    .Select(x => x.ProjectId);

var orphanProjects =  session.QueryOver<ProjectModel>()
                         .WithSubquery
                         .WhereProperty(x=>x.Id)
                         .NotIn(notOrphanProjectIdsSubquery)
                         .List();

----------------------- 初步回答

假设您的Finances课程中有一个已映射的Project媒体资源,并且根据https://stackoverflow.com/a/14980450/1236044,它应该是这样的:

var orphanProjects = session.QueryOver<ProjectModel>()
    .WhereRestrictionOn(x => x.Finances).IsEmpty()
    .List();

我必须承认我不熟悉FluentNH。我想类和映射应该是这样的,希望我不会让你走错路......

public class FinanceModel
{
    public virtual int Id { get; set; }
    public virtual int ProjectId { get; set; }       
    public virtual ProjectModel Project{get;set;}
}

public class ProjectModel
{
    public virtual int Id { get; set; }
    public virtual string ProjectName { get; set; }
    public virtual IList<FinanceModel> Finances { get; set; }
}


public class ProjectMap:ClassMap<ProjectModel>
{
    public ProjectMap() {
        Table("Projects");
        Id(x => x.Id);
        Map(x => x.ProjectName);
        HasMany(x => x.Finances);
    }
}

public class FinanceMap : ClassMap<FinanceModel>
{
    public FinanceMap()
    {
        Table("Finances");
        Id(x => x.Id);
        References(x => x.Project);
    }
}