I think that I have now searched the Internet in all possible ways, and I didn't find the answer, or maybe just didn't understand the answer good enough to implement it into my current project. So I'm very happy with a solution here.
It's about planning, and as illustrated I have a machine, that run any hour during the week. But, in a "Nonproduction" table, I have timespans (estimatedStart - estimatedStop), where production is not possible. A nonProduction record, can be for a specific machine - but it can also be for the company. In that case the machineID will be null.
SO, what I want is to select a machine with all it's nonProduction records AND the nonProduction records where machineId is null.
The SQL statement would be VERY easy!
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;
My fluent Machine mapping goes here: (Some code has been removed for clarity)
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();
}
}
Repository code here:
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();
}
I know that the "n.MachineId == m.MachineId" in the restriction part is implied, but as I started to write, I really can't find a nice solution here.
I have to mention, that the database is very old, and contains a lot of data, so it is unfortunately not possible to re-design it. :(
I do not believe this to be doable by mappings.
I would map in the one-to-many only the machine bound nonProduction entities.
The general ones (without a machine id) would be loaded by a dedicated query, and you would merge the two lists for your processing.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.