{"action":"created","issue":{"url":"https://api.github.com/repos/linq2db/linq2db/issues/510","repository_url":"https://api.github.com/repos/linq2db/linq2db","labels_url":"https://api.github.com/repos/linq2db/linq2db/issues/510/labels{/name}","comments_url":"https://api.github.com/repos/linq2db/linq2db/issues/510/comments","events_url":"https://api.github.com/repos/linq2db/linq2db/issues/510/events","html_url":"https://github.com/linq2db/linq2db/issues/510","id":196691127,"number":510,"title":"F# option types and treating null as None","user":{"login":"jjj-herobase","id":17162099,"avatar_url":"https://avatars.githubusercontent.com/u/17162099?v=3","gravatar_id":"","url":"https://api.github.com/users/jjj-herobase","html_url":"https://github.com/jjj-herobase","followers_url":"https://api.github.com/users/jjj-herobase/followers","following_url":"https://api.github.com/users/jjj-herobase/following{/other_user}","gists_url":"https://api.github.com/users/jjj-herobase/gists{/gist_id}","starred_url":"https://api.github.com/users/jjj-herobase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jjj-herobase/subscriptions","organizations_url":"https://api.github.com/users/jjj-herobase/orgs","repos_url":"https://api.github.com/users/jjj-herobase/repos","events_url":"https://api.github.com/users/jjj-herobase/events{/privacy}","received_events_url":"https://api.github.com/users/jjj-herobase/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"ili","id":787292,"avatar_url":"https://avatars.githubusercontent.com/u/787292?v=3","gravatar_id":"","url":"https://api.github.com/users/ili","html_url":"https://github.com/ili","followers_url":"https://api.github.com/users/ili/followers","following_url":"https://api.github.com/users/ili/following{/other_user}","gists_url":"https://api.github.com/users/ili/gists{/gist_id}","starred_url":"https://api.github.com/users/ili/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ili/subscriptions","organizations_url":"https://api.github.com/users/ili/orgs","repos_url":"https://api.github.com/users/ili/repos","events_url":"https://api.github.com/users/ili/events{/privacy}","received_events_url":"https://api.github.com/users/ili/received_events","type":"User","site_admin":false},"assignees":[{"login":"ili","id":787292,"avatar_url":"https://avatars.githubusercontent.com/u/787292?v=3","gravatar_id":"","url":"https://api.github.com/users/ili","html_url":"https://github.com/ili","followers_url":"https://api.github.com/users/ili/followers","following_url":"https://api.github.com/users/ili/following{/other_user}","gists_url":"https://api.github.com/users/ili/gists{/gist_id}","starred_url":"https://api.github.com/users/ili/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ili/subscriptions","organizations_url":"https://api.github.com/users/ili/orgs","repos_url":"https://api.github.com/users/ili/repos","events_url":"https://api.github.com/users/ili/events{/privacy}","received_events_url":"https://api.github.com/users/ili/received_events","type":"User","site_admin":false}],"milestone":null,"comments":3,"created_at":"2016-12-20T14:49:55Z","updated_at":"2016-12-21T06:00:04Z","closed_at":null,"body":"Hi\r\n\r\nFirst of all, Thanks to everyone who've made and contributed to this awesome project. It is [insert superlative more praising than awesome here]!!\r\n\r\nTo business:\r\n\r\nI've been looking into how to add support for F# option types. I started by looking at PR #194, but it seems outdated and wrongish. \r\nI eventually found out that simply adding the desired option types as scalar types makes everything work (almost), and an appropriate converter.\r\nCurrently I do this:\r\n```\r\ndb.MappingSchema.AddScalarType(typeof<string option>,          None, false, LinqToDB.DataType.NVarChar)\r\ndb.MappingSchema.AddScalarType(typeof<decimal option>,         Option.None, false, LinqToDB.DataType.Decimal)\r\ndb.MappingSchema.AddScalarType(typeof<DateTime option>,        None, false, LinqToDB.DataType.DateTime2)\r\n\r\ndb.MappingSchema.SetConvertExpression<Option<_>,_>( fun x -> if x.IsSome then x.Value else None );\r\n\r\n```\r\n\r\nI haven't tested with more complex types, but since this is mainly an alternative to using null in F#, and since databases generally don't support complex types, I don't think it's going to be an issue.\r\n\r\nThe only remaining problem is that, this check:\r\n```\r\n// Add check null expression.\r\n//\r\nif (dataContext.IsDBNullAllowed(dataReader, idx) ?? true)\r\n{\r\n\tex = Condition(\r\n\t\tCall(dataReaderExpr, _isDBNullInfo, Constant(idx)),\r\n\t\tConstant(mappingSchema.GetDefaultValue(type), type),\r\n\t\tex);\r\n}\r\n```\r\nIn ConvertFromDataReaderExpression.cs:GetColumnReader: (line 111 in my version). \r\nChecks that the actual db field is nullable and sets the result as null if true. That happens even though I've marked my scalar types as not nullable and even though I've added NotNull attribute to my property.\r\n\r\nIs there are way to force the converter to run, or at least use the default value if the scalar type is not nullable? So that I could get a proper none instead of null.\r\n\r\nThis is not a major thing since F# happily pattern matches null as None.\r\n\r\nThe mapped type\r\n```\r\ntype [<Table(Name = \"billing_group_call_type_parameter\", IsColumnAttributeRequired = false)>] BillingGroupEndpointTypeParameter = {\r\n    id: int\r\n    agent_line_multiplier: Nullable<decimal>\r\n    [<NotNull>]\r\n    price_per_connect: decimal<euro> option\r\n    [<Column(Name = \"call_type_id\")>] \r\n    EndpointType: EndpointType \r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/linq2db/linq2db/issues/comments/268442888","html_url":"https://github.com/linq2db/linq2db/issues/510#issuecomment-268442888","issue_url":"https://api.github.com/repos/linq2db/linq2db/issues/510","id":268442888,"user":{"login":"ili","id":787292,"avatar_url":"https://avatars.githubusercontent.com/u/787292?v=3","gravatar_id":"","url":"https://api.github.com/users/ili","html_url":"https://github.com/ili","followers_url":"https://api.github.com/users/ili/followers","following_url":"https://api.github.com/users/ili/following{/other_user}","gists_url":"https://api.github.com/users/ili/gists{/gist_id}","starred_url":"https://api.github.com/users/ili/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ili/subscriptions","organizations_url":"https://api.github.com/users/ili/orgs","repos_url":"https://api.github.com/users/ili/repos","events_url":"https://api.github.com/users/ili/events{/privacy}","received_events_url":"https://api.github.com/users/ili/received_events","type":"User","site_admin":false},"created_at":"2016-12-21T06:00:04Z","updated_at":"2016-12-21T06:00:04Z","body":"Can you write pseudo code you are expecting on reading `Option` from `DataReader`? \r\nfor ex\r\n```cs\r\nvar value = dataReader.IsNull(0) == null ? Option.None : dataReader.GetValue(0);\r\n```"}}
{"actor":{"display_login":"ili"}}