Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata Semantics Too Verbose #262

Open
groogiam opened this issue Dec 1, 2018 · 6 comments
Open

Metadata Semantics Too Verbose #262

groogiam opened this issue Dec 1, 2018 · 6 comments

Comments

@groogiam
Copy link

groogiam commented Dec 1, 2018

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.

db.Query<TestDataEntity>().Select(s => new Document<TestDataEntity>
			{
				Id = N1QlFunctions.Meta(s).Id,
				Cas = N1QlFunctions.Meta(s).Cas,
				Content = s
			}).First()

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.

@brantburnett
Copy link
Collaborator

@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 class. Then you can collect the metadata using a single call.

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.

@groogiam
Copy link
Author

groogiam commented Dec 2, 2018

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?

@brantburnett
Copy link
Collaborator

It shouldn’t because it’s internally using Select to alter the Queryable, and it’s not within a lambda itself.

@groogiam
Copy link
Author

groogiam commented Dec 2, 2018

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?

@jeffrymorris
Copy link
Contributor

@groogiam -

Yeah, that seems like a bug:

https://github.com/couchbaselabs/Linq2Couchbase/blob/master/Src/Couchbase.Linq/Metadata/DocumentMetadata.cs#L16

Cas should be a ulong - unless @brantburnett has some more insight?

@brantburnett
Copy link
Collaborator

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants