我有一个乌鸦驱动的应用程序,我正在尝试实现Cascading Deletion Bundle。设置看起来非常简单,但是我的1个关于级联的文档中的映射设置部分有点不清楚。无论如何,这是我的设置,感谢您的帮助。
// An album class with no reference to photos
class Album
{
public string Id { get; set; } //ID for album from raven
}
// A photo class with a reference to its parent album
class Photo
{
public string Id { get; set; } //ID for photo from raven
public string PhotoName { get; set; }
public Album PhotoAlbum { get; set; }
}
// On album store
session.Store(album);
session.Advanced.GetMetadataFor(album)["Raven-Cascade-Delete-Documents"] =
RavenJToken.FromObject(new[] { album.Id });
// THIS DOES NOT WORK, But I was assuming that it would search for each document
// with a reference to an album and delete it.
答案 0 :(得分:3)
首先,在对文档之间的引用建模时,需要引用外部文档键,而不是整个文档。你现在拥有的将把这张专辑嵌入到文档中。这样做:
public class Photo
{
public string Id { get; set; }
public string PhotoName { get; set; }
public string AlbumId { get; set; }
}
关于级联删除,捆绑包只是在删除文档时查看元数据并删除所引用的任何文档。 不帮助您构建开始的文档列表。你必须自己做。每次添加照片时,您都会加载相册并将照片的ID添加到相册的级联删除列表中。
因此,在保存相册和前几张照片时:
using (var session = documentStore.OpenSession())
{
var album = new Album();
session.Store(album);
var photoA = new Photo { PhotoName = "A", AlbumId = album.Id };
var photoB = new Photo { PhotoName = "B", AlbumId = album.Id };
var photoC = new Photo { PhotoName = "C", AlbumId = album.Id };
session.Store(photoA);
session.Store(photoB);
session.Store(photoC);
session.Advanced.AddCascadeDeleteReference(album,
photoA.Id,
photoB.Id,
photoC.Id);
session.SaveChanges();
}
然后,将照片添加到现有相册
using (var session = documentStore.OpenSession())
{
// you would know this already at this stage
const string albumId = "albums/1";
var photoD = new Photo { PhotoName = "D", AlbumId = albumId };
session.Store(photoD);
var album = session.Load<Album>(albumId);
session.Advanced.AddCascadeDeleteReference(album, photoD.Id);
session.SaveChanges();
}
以下是我在上面使用的AddCascadeDeleteReference
扩展方法。你可以自己做,但这会让事情变得容易些。把它放在静态类中。
public static void AddCascadeDeleteReference(
this IAdvancedDocumentSessionOperations session,
object entity, params string[] documentKeys)
{
var metadata = session.GetMetadataFor(entity);
if (metadata == null)
throw new InvalidOperationException(
"The entity must be tracked in the session before calling this method.");
if (documentKeys.Length == 0)
throw new ArgumentException(
"At least one document key must be specified.");
const string metadataKey = "Raven-Cascade-Delete-Documents";
RavenJToken token;
if (!metadata.TryGetValue(metadataKey, out token))
token = new RavenJArray();
var list = (RavenJArray) token;
foreach (var documentKey in documentKeys.Where(key => !list.Contains(key)))
list.Add(documentKey);
metadata[metadataKey] = list;
}