使用外部对象更新文档 [英] Update Document with external object

查看:49
本文介绍了使用外部对象更新文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 Song 对象的数据库.歌曲类有 > 30 个属性.

i have a database containing Song objects. The song class has > 30 properties.

我的音乐标记应用程序正在对文件系统上的歌曲进行更改.然后它使用文件名在数据库中进行查找.

My Music Tagging application is doing changes on a song on the file system. It then does a lookup in the database using the filename.

现在我有一个 Song 对象,它是我通过读取物理文件在我的 Tagging 应用程序中创建的,我有一个 Song 对象,我刚刚从数据库中检索了它并且我想更新它.我以为我可以从数据库对象中获取 ID,用我的本地歌曲对象替换数据库对象,设置保存的 ID 并存储它.但是 Raven 声称我正在用不同的对象替换该对象.

Now i have a Song object, which i created in my Tagging application by reading the physical file and i have a Song object, which i have just retrieved from the database and which i want to update. I thought i just could grab the ID from the database object, replace the database object with my local song object, set the saved id and store it. But Raven claims that i am replacing the object with a different object.

我真的需要像这样复制每个属性吗?

Do i really need to copy every single property over, like this?

dbSong.Artist = songfromFilesystem.Artist;

dbSong.Artist = songfromFilesystem.Artist;

dbSong.Album = songfromFileSystem.Album;

dbSong.Album = songfromFileSystem.Album;

或者还有其他可能性.

谢谢,

赫尔穆特

我有点过于积极了.以下建议仅适用于测试程序.在我的原始代码中执行此操作时,我收到以下异常:

I was a bit too positive. The suggestion below works only in a test program. When doing it in my original code i get following exception:

Attempted to associate a different object with id 'TrackDatas/3452'

这是由以下代码生成的:

This is produced by following code:

try
  {
    originalFileName = Util.EscapeDatabaseQuery(originalFileName);
    // Lookup the track in the database
    var dbTracks = _session.Advanced.DocumentQuery<TrackData, DefaultSearchIndex>().WhereEquals("Query", originalFileName).ToList();
    if (dbTracks.Count > 0)
    {
      track.Id = dbTracks[0].Id;
      _session.Store(track);
      _session.SaveChanges();
    }
  }
  catch (Exception ex)
  {
    log.Error("UpdateTrack: Error updating track in database {0}: {1}", ex.Message, ex.InnerException);
  }

我首先在数据库中查找歌曲并在 dbTracks 中获取一个 TrackData 对象.

I am first looking up a song in the database and get a TrackData object in dbTracks.

track 对象也是 TrackData 类型,我只是将刚刚检索到的对象的 ID 放入并尝试存储它,这会导致上述错误.

The track object is also of type TrackData and i just put the ID from the object just retrieved and try to store it, which gives the above error.

我认为上面的消息告诉我对象是不同类型的,而它们不是.

I would think that the above message tells me that the objects are of different types, which they aren't.

如果我使用 AutoMapper,也会发生同样的错误.

The same error happens, if i use AutoMapper.

有什么想法吗?

推荐答案

您可以执行您正在尝试的操作:仅使用 ID 替换现有对象.如果它不起作用,您可能做错了其他事情.(在这种情况下,请向我们展示您的代码.)

You can do what you're trying: replace an existing object using just the ID. If it's not working, you might be doing something else wrong. (In which case, please show us your code.)

在 Raven 中更新现有对象时,有几个选项:

When it comes to updating existing objects in Raven, there are a few options:

选项 1:使用与现有对象相同的 ID 保存对象:

Option 1: Just save the object using the same ID as an existing object:

var song = ... // load it from the file system or whatever
song.Id = "Songs/5"; // Set it to an existing song ID
DbSession.Store(song); // Overwrites the existing song

选项 2:手动更新现有对象的属性.

Option 2: Manually update the properties of the existing object.

var song = ...;
var existingSong = DbSession.Load<Song>("Songs/5");
existingSong.Artist = song.Artist;
existingSong.Album = song.Album;

选项 3:动态更新现有对象:

Option 3: Dynamically update the existing object:

var song = ...;
var existingSong = DbSession.Load<Song>("Songs/5");
existingSong.CopyFrom(song);

你有这样的代码:

// Inside Song.cs
public virtual void CopyFrom(Song other)
{
    var props = typeof(Song)
        .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
        .Where(p => p.CanWrite);
    foreach (var prop in props)
    {
        var source = prop.GetValue(other);
        prop.SetValue(this, source);
    }
}

如果您发现自己必须经常这样做,请使用像 AutoMapper 这样的库.

If you find yourself having to do this often, use a library like AutoMapper.

Automapper 可以用一行代码自动将一个对象复制到另一个对象.

Automapper can automatically copy one object to another with a single line of code.

这篇关于使用外部对象更新文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆