Open groogiam opened 5 years ago
@groogiam,
If your primary purpose is to support writing back to the document, I'd recommend using change tracking. This automates the Id and Cas handling for you. https://github.com/couchbaselabs/Linq2Couchbase/blob/master/docs/change-tracking.md
If you need more fine-grained control, I normally use anonymous objects instead of the Document
db.Query<TestDataEntity>().Select(s => new
{
Meta = N1QlFunctions.Meta(s),
Content = s
}).First()
That said, selecting directly into a Document class is an interesting idea. An extension method should be able to accomplish that pretty easily:
public static class Extensions
{
public static IQueryable<Document<T>> SelectDocument<T>(this IQueryable<T> source)
{
return source.Select(p => new Document<T>
{
Id = N1QlFunctions.Meta(p).Id,
Cas = N1QlFunctions.Meta(p).Cas,
Content = p
});
}
}
Then you could easily repeat the process without as much lift:
db.Query<TestDataEntity>().SelectDocument().First()
Let me know how that works for you and maybe we'll make it a built-in extension.
I'm not sure that the extension method will work. Won't the provider throw a not supported exception because as it will try to translate the function to N1QL?
It shouldn’t because it’s internally using Select to alter the Queryable, and it’s not within a lambda itself.
I think there is an issue with the Cas data types. Document uses ulong while the N1QlFunctions.Meta uses a double for some reason. Converting in the extension method throws an unsupported exception. Is there a reason why the Cas is a double in Linq2Couchbase?
@groogiam -
Yeah, that seems like a bug:
Cas should be a ulong - unless @brantburnett has some more insight?
@jeffrymorris
I did some digging, and it appears to be a mistake I made in the early days that lives on. I can't recall any specific reason I would have chosen double instead of ulong.
Our problem now is that fixing it will be a breaking change, requiring us to bump to 2.x. I suppose we could do something with an additional property with some typecasting? But seems messy.
The semantics for retrieving metadata seem rather verbose. In order to populate a Document I have I have to call the Meta function several times.
It really seems like there should be a way to just directly map the metadata to a Document or even better to properties on the POCO object. Something like the BsonIdAttribute in MongoDb.