C# 版本控制算法

C# 版本控制算法,c#,sql,algorithm,C#,Sql,Algorithm,我有一个存储对象的数据库。我有下面的简化模式 CREATE TABLE MyObjects ( UniqueIdentifier Id; BigInt GenerationId; BigInt Value; Bit DeleteAction; ) 每个对象都有一个唯一的标识符Id和一组属性值。每次更改对象的属性值时,我都会使用新的GenerationId GenerationId在该表中输入一个新行,该id是单调

我有一个存储对象的数据库。我有下面的简化模式

CREATE TABLE MyObjects
(
  UniqueIdentifier Id;
  BigInt           GenerationId;
  BigInt           Value;
  Bit              DeleteAction;
)
每个对象都有一个唯一的标识符Id和一组属性值。每次更改对象的属性值时,我都会使用新的GenerationId GenerationId在该表中输入一个新行,该id是单调递增的。如果删除了一个对象,那么我通过将DeleteAction位设置为true来记录这一事实

在生成的任何时间点,我都希望检索所有活动对象的状态

下面是一个例子:

Id    GenerationId Value  DeleteAction
1        1          99       false
2        1          88       false
1        2          77       false
2        3          88       true
世代中的对象包括:

  1: 1 {99}, 2 {88}
  2: 1 {77}, 2 {88}
  3: 1 {77}

关键是:我如何找出每个唯一对象的行,谁的生成id最接近但不超过给定的生成id?然后,我可以执行后期筛选步骤,删除DeleteAction字段为true的所有行。

不确定这是否是标准SQL,但在Postgres中,可以使用LIMIT标志:

 select GenerationId,Value,DeleteAction from MyObjects 
    where Id=1 and GenerationId < 3 
    order by GenerationId
    limit 1;
这适用于MS SQL

SELECT id,value
FROM Myobjects
INNER JOIN ( 
     SELECT id, max(GenerationID) as LastGen 
     FROM MyObjects
     WHERE GenerationID <= @Wantedgeneration
     Group by ID)
    On GenerationID = LastGen
WHERE DelectedAction = false

我的版本使用表MyObject的关节与 自身的子集,由子查询创建,仅包含最后一个 为每个对象生成:

SELECT O.id,generation,value FROM 
     MyObjects O, 
     (SELECT id,max(generation) AS max_generation FROM MyObjects 
     WHERE generation <= $GENERATION_ID GROUP BY id) AS TheMax WHERE 
            TheMax.max_generation = generation AND O.deleted is False
     ORDER BY generation DESC;
我得到:

> SELECT * FROM generation_objects(1) ORDER by generation DESC;
 id | generation | value | deleted 
----+------------+-------+---------
  1 |          1 |    99 | f

> SELECT * FROM generation_objects(2) ORDER by generation DESC;
 id | generation | value | deleted 
----+------------+-------+---------
  2 |          2 |    88 | f
  1 |          1 |    99 | f

> SELECT * FROM generation_objects(3) ORDER by generation DESC;
 id | generation | value | deleted 
----+------------+-------+---------
  1 |          3 |    77 | f
  2 |          2 |    88 | f
然后,在下一代中,删除对象2:

> SELECT * FROM generation_objects(4) ORDER by generation DESC;
 id | generation | value | deleted 
----+------------+-------+---------
  1 |          3 |    77 | f

以下是工作版本:

SELECT MyObjects.Id,Value
FROM Myobjects
INNER JOIN 
(      
  SELECT Id, max(GenerationId) as LastGen
  FROM MyObjects
  WHERE GenerationId <= @TargetGeneration
  Group by Id
) T1
ON MyObjects.Id = T1.Id AND MyObjects.GenerationId = LastGen
WHERE DeleteAction = 'False'

我不会在示例中关注您的对象。你能澄清一下吗?在这个例子中有一个输入错误,似乎GenerationID1被使用了两次。不,重点是要表明对象1和2都是在同一个Generation1中添加的。源代码管理的一个例子是在一个变更集中添加2个文件,其中生成是变更集编号。问题的关键不是必须指定Id=1,而是返回所有符合生成要求的Id。是的,应该这样做。至少这是一个很好的起点+1.
> SELECT * FROM generation_objects(4) ORDER by generation DESC;
 id | generation | value | deleted 
----+------------+-------+---------
  1 |          3 |    77 | f
SELECT MyObjects.Id,Value
FROM Myobjects
INNER JOIN 
(      
  SELECT Id, max(GenerationId) as LastGen
  FROM MyObjects
  WHERE GenerationId <= @TargetGeneration
  Group by Id
) T1
ON MyObjects.Id = T1.Id AND MyObjects.GenerationId = LastGen
WHERE DeleteAction = 'False'