Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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# 查询帮助:如果列已复制,请将“原始”保留在“选择”之外_C#_Linq To Sql - Fatal编程技术网

C# 查询帮助:如果列已复制,请将“原始”保留在“选择”之外

C# 查询帮助:如果列已复制,请将“原始”保留在“选择”之外,c#,linq-to-sql,C#,Linq To Sql,因此,我有一个表来保存这些“资产”,比如说有25个“特殊资产”,用户无法编辑,因为它们是共享的。但是,作为一种允许用户编辑资产并拥有自己版本的方法,它会制作原始资产的副本,然后允许用户进行编辑。表中的行在复制后保存一个名为OriginalAssetID的值(否则为零)。现在的问题是:我们不希望原始资产在浏览资产时再为该用户显示。一旦他们制作了原始资产的个人副本,只有他们的新个人副本才应该显示,而不是两者都显示。那么,我如何才能进行一个查询,说获取所有这些资产,但不获取包含属于某个选定资产Orig

因此,我有一个表来保存这些“资产”,比如说有25个“特殊资产”,用户无法编辑,因为它们是共享的。但是,作为一种允许用户编辑资产并拥有自己版本的方法,它会制作原始资产的副本,然后允许用户进行编辑。表中的行在复制后保存一个名为OriginalAssetID的值(否则为零)。现在的问题是:我们不希望原始资产在浏览资产时再为该用户显示。一旦他们制作了原始资产的个人副本,只有他们的新个人副本才应该显示,而不是两者都显示。那么,我如何才能进行一个查询,说获取所有这些资产,但不获取包含属于某个选定资产OriginalAssetID列的assetID的资产?请记住,我不能在原始资源本身上标记任何内容,因为它是由尚未制作副本的其他用户共享的,他们仍然会在浏览列表中看到它。祝你好运,几个小时来我一直在想这个问题

(SQL Server 2005)

要添加一些示例:

资产一: 资产id=5 原始id=0

资产二(1的副本): 资产id=12 原始id=5


因此,在这种情况下,我们只想取回资产二,而不再取回资产一,因为它现在被复制,复制的版本应该是活动版本,但我们无法摆脱它,因为其他一些用户可能还没有复制它,因此他们希望资产一仍然

这还没有经过测试,但我相信它会起作用

SELECT * FROM Assets WHERE user_id = 99 AND asset_id NOT IN 
(SELECT original_asset_id FROM Assets WHERE user_id = 99 AND original_asset_id <> 0)
那怎么办

   Select IsNull(p.AssetId, o.AssetId) AssetId,
          IsNull(p.AssetName, o.AssetName) AssetName,
          IsNull(p.AssetAge, o.AssetAge) AssetAge
      -- etc.
   From Assets o
      Left Join Assets p
         On p.OrigAssetId = o.AssetId
            And p.userId = @MyUserId

在Select子句中,只需添加所有要输出的列。。。对于每一个,如果表中有一个特定于用户的行,则
IsNull
将从该外部联接表输出值,如果没有,则每个
IsNull
中的第一个参数将为null,并且所有
IsNull
将从非特定于用户的行输出默认值

这是SQL,但您可以轻松地将其转换为Linq

SELECT * 
FROM Assets 
WHERE user_id = @user_id
UNION ALL
SELECT * FROM Assets 
WHERE 
   original_asset_id = 0
   and asset_id NOT IN 
      (SELECT original_asset_id FROM Assets WHERE user_id = @user_id)

第一个选择返回用户覆盖的所有资产。第二次选择返回所有未被用户覆盖的资产。

这应该在linq中完成:

var assets = new object[]{}; //your assets enumerable
var userAsserts = (from asset in assets
                  select new {Id = asset.OriginalAssetID == 0 ? asset.ID : asset.OriginalAssetID, Asset= asset).OrderByDescending(a => a.OriginalAssetID).Distinct(a => a.Id);

我相信“不存在”在这种情况下会起作用:

select asset_id
from assets a
where not exists (select * from assets where orig_asset_id = a.asset_id)

发布您的表架构会很有帮助。因此,为了澄清:查找用户的所有资产,但如果它具有OriginalAssetID,则不获取原始资产。Matt:是的,如果它具有OriginalAssetID,我们希望获取它,但现在我们不希望OriginalAssetID指定的原始资产也可以被覆盖(id 12)?如果是,则它看起来像传递闭包,而不是无法在SQL中表示的闭包。不,只有某些资产可以复制,并且只有复制一次。如果用户没有覆盖默认资产,则返回空结果。我相信在这种情况下,它应该返回默认资产。所以你的意思是,有些资产没有用户id集,也需要返回?嗯,很有趣……我们想得到一些具有原始资产id的资产!=另外,我们不希望在原始\u asset\u id列中显示的是AssetIDget@Ryan对不起,我有点困惑。也许您应该提供表结构来澄清这一点。基本上:获取所有资产,如果其中任何资产的OriginalID不为零,则从集合中移除所有资产,这些资产的AssetID位于当前选择的任何资产OrignalID列中,这有意义吗?我不会这样说。但基本上是的。
select asset_id
from assets a
where not exists (select * from assets where orig_asset_id = a.asset_id)