流畅的nHibernate连接id和null值

时间:2017-02-08 17:38:52

标签: c# join nhibernate asp.net-mvc-5 fluent

我认为我现在已经以各种可能的方式搜索了互联网,但我没有找到答案,或者可能只是不理解答案足以将其实施到我当前的项目中。所以我对这里的解决方案非常满意。

这是关于计划,如图所示,我有一台机器,在一周内的任何一小时运行。但是,在“非生产”表中,我有时间间隔(估计开始 - 估计停止),生产是不可能的。非生产记录可以用于特定的机器 - 但也可以用于公司。在这种情况下,machineID将为null。

所以,我想要的是选择一台具有所有非生产记录的机器和非生产记录,其中machineId为空。

Diagram from MySQL

SQL语句非常简单!

select * from machine m
left outer join nonproduction np on (m.machine_id = np.machineID or np.machineID is null)
where m.machine_id=119;

The select result from the above SQL

我的流畅机器映射在这里:(为清晰起见,已删除了一些代码)

public class MachineMap : ClassMap<Machine>
    {
        public MachineMap()
        {
            Table("machine");
            Id(x => x.MachineId, "machine_id").GeneratedBy.Identity();
            Map(x => x.Name, "name");
            Map(x => x.Number, "machinenumber");
            Map(x => x.Size, "size");
            Map(x => x.Data1, "data1");
            Map(x => x.Data2, "data2");
            Map(x => x.Data3, "data3");

            HasMany(x => x.NonProductions)
                .KeyColumn("machineID").KeyNullable()
                .AsBag();

        }
    }

public class NonProductionMap : ClassMap<NonProduction>
        {
            public NonProductionMap()
            {
                Table("nonproduction");
                Id(x => x.NonproductionId, "Nonproduction_id").GeneratedBy.Identity();
                Map(x => x.NonproductionTypeId, "nonproduction_typeID");
                Map(x => x.MachineId, "machineID").Nullable();
                Map(x => x.WorkerId, "workerID");
                Map(x => x.EstimatedStart, "estimated_start");
                Map(x => x.EstimatedStop, "estimated_stop");
                Map(x => x.Visible, "nonproductionvisible");
                Map(x => x.Repetitiontime, "repetitiontime");

                References(x => x.Machine)
                    .Column("machineID")
                    .Not.Insert()
                    .Not.Update();
            }
        }

这里的存储库代码:

public IEnumerable<Machine> GetMachinesForCalendar(int[] ids = null)
    {
        Machine m = null;
        Order o = null;
        NonProduction n = null;

        var query = Session.QueryOver(() => m)
            .JoinAlias(() => m.Orders, () => o, JoinType.LeftOuterJoin)
            .JoinAlias(() => m.NonProductions, () => n, JoinType.LeftOuterJoin, Restrictions.Where(() => n.MachineId == m.MachineId || n.MachineId == null));

        if (ids != null && ids.Any())
        {
            query = query
                .WhereRestrictionOn(() => m.MachineId)
                .IsIn(ids);
        }

        return query
            .List()
            .Distinct()
            .ToList();

    }

我知道限制部分中的“n.MachineId == m.MachineId”是暗示的,但是当我开始写作时,我真的找不到一个好的解决方案。

我必须提一下,数据库非常老,并且包含大量数据,所以遗憾的是不可能重新设计它。 :(

1 个答案:

答案 0 :(得分:0)

我不相信这可以通过映射来实现。

我会在一对多地图中映射机器绑定的非生产实体。

一般的(没有机器ID)将由专用查询加载,您将合并这两个列表进行处理。