I tried to make a primary key for Member entity, I don't want to use annotation, just use fluent API:
Member{
public string MemberID {get;set;}
...
}
In MemberMapping
this.hasKey(t=>t.MemberID);
When update database I got this error:
Identity column 'MemberID' must be of data type int, bigint, smallint, tinyint, or decimal or numeric with
a scale of 0, and constrained to be nonnullable
EF supports string as PK but you have to set explicitly that property with some value when you need to create an Member's instance and save it into your DB. The only type that is identity by default in EF is int. To fix your problem I think you have two options:
Change the MemberID column in your database to not be Identity. That should solve the problem.
If you want that EF do that change for you then add this configuration:
this.hasKey(t=>t.MemberID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Create a new migration using the Add-Migration command and try to run again Update-Database command.
Now,if your MemberID column in your DB isn't Identity and you are trying to set as Identity the MemberID PK property in your model, that also could be the cause of your issue. If that is the case, remove that configuration and try to run again Update-Database command.
From Programming Entity Framework Code First book, page 44:
In the case where the Key field is an Integer, Code First defaults to
DatabaseGeneratedOption.Identity. With a Guid, you need to explicitly
configure this. These are the only types that you can configure to be
Identity when Code First is generating the database.
the problem is not the PK but the indentity. You should have something like
property(x => x.MemberID).HasDatabaseGeneratedOption(
DatabaseGeneratedOption.None);
Related
Our DBA don't want us to use double quoted fields and tables in our queries (don't ask me the reason)... the problem is that ServiceStack.OrmLite double quote them all, and I don't have any idea on how disable this behaviour. We are using ServiceStack.OrmLite Version 4.5.4.0.
For example:
public class ClassA {
public int ID {get;set;}
public string Name {get;set;}
}
If we make a simple query like:
using (IDbConnection db = dbFactory.Open())
{
return db.LoadSingleById<ClassA>(id);
}
would generate:
select "ID", "Name" from "ClassA" where "ID" = #0
And this is what our dba want:
select ID, Name from ClassA where ID = #0
If anybody could help, I would apreciate a lot
PS I know I can write myself all queries, but there are too much code to change, so I'm trying to avoid this solution because it's too much time consuming at the moment.
Based on my inspection of the source code, it appears that this cannot be changed out of the box.
When ORMLite builds its query, it grabs the column name and wraps it in quotation marks. See here: https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs#L384
An alternative would be to create a new OrmLiteDialectProvider that inherits whichever provider you are using (e.g., SQL Server, Oracle, etc), and override one of the following methods:
GetQuotedColumnName(string columnName)
GetQuotedName(string name)
Overriding either of those to exclude the quotation marks would get you what you're looking for.
My entity has a field
#Column("authorizations")
#Builder.Default
private Map<String, Set<String>> authorizations = new HashMap<>();
When I query for that object via Spring Data repository I'm getting an exception
CodecNotFoundException: Codec not found for requested operation:
[set <-> java.util.Set]
Writes work just fine though. I can't believe this is not supported out of the box.
Table definition
CREATE TABLE resource_authorization_rules(
resource text,
region text,
authorizations map<text, frozen<set<text>>>,
PRIMARY KEY (resource, region)
);
Probably something with type erasure. How to tackle this with least effort?
This is a limitation of the the Spring Data Casasndra. There is a JIRA for improving support of frozen collections. And it looks like that it could be worked around with custom row mapper as described here.
P.S. The DataStax Java Driver has corresponding annotations in their object mapper.
ASP.NET Identity 2.0 dbo.AspNetUsers defined as a string:
Id = c.String(nullable: false, maxLength: 128)
When it could be defined as integer:
Id = c.Int(nullable: false, identity: true)
Why is that so? What are the +/- of this?
Does it makes sense to change it to integer or there's a risk of screwing everything?
In addition to already linked answer - Identity is built so it can accommodate any kind of storage. I've seen Azure Tables and plain text files storage implemented. And not all of these can use int/Guid as a primary key, or even have a primary key at all.
So the lowest common denominator for any system - a string. But it can be changed to an int or Guid or whatever your storage supports.
Don't change it. If you notice, the UserManager class works only where the primary key is of type string.
Can anyone tell me how to correctly get ORMLite to store enums as integers? I know that this was not supported in 2012 but i found code for some unit tests that suggest it should work now but it doesn't. When we try the column gets created as a varchar(max) in ms sql. We currently use a wrapping property that is ignored to convert the enum value to int but then you can't use it for queries etc so it is less than ideal.
Add a [Flags] attribute to enums you want ServiceStack to treat as integers.
From v4.0.54 you can also use the [EnumAsInt] attribute which will save the enum as an int in OrmLite but still serialize it as a string.
After spending a year working with the Microsoft.Xrm.Sdk namespace, I just discovered yesterday the Entity.FormattedValues property contains the text value for Entity specific (ie Local) Option Set texts.
The reason I didn't discover it before, is there is no early bound method of getting the value. i.e. entity.new_myOptionSet is of type OptionSetValue which only contains the int value. You have to call entity.FormattedValues["new_myoptionset"] to get the string text value of the OptionSetValue.
Therefore, I'd like to get the crmsrvcutil to auto-generate a text property for local option sets. i.e. Along with Entity.new_myOptionSet being generated as it currently does, Entity.new_myOptionSetText would be generated as well.
I've looked into the Microsoft.Crm.Services.Utility.ICodeGenerationService, but that looks like it is mostly for specifying what CodeGenerationType something should be...
Is there a way supported way using CrmServiceUtil to add these properties, or am I better off writing a custom app that I can run that can generate these properties as a partial class to the auto-generated ones?
Edit - Example of the code that I would like to be generated
Currently, whenever I need to access the text value of a OptionSetValue, I use this code:
var textValue = OptionSetCache.GetText(service, entity, e => e.New_MyOptionSet);
The option set cache will use the entity.LogicalName, and the property expression to determine the name of the option set that I'm asking for. It will then query the SDK using the RetrieveAttriubteRequest, to get a list of the option set int and text values, which it then caches so it doesn't have to hit CRM again. It then looks up the int value of the New_MyOptionSet of the entity and cross references it with the cached list, to get the text value of the OptionSet.
Instead of doing all of that, I can just do this (assuming that the entity has been retrieved from the server, and not just populated client side):
var textValue = entity.FormattedValues["new_myoptionset"];
but the "new_myoptionset" is no longer early bound. I would like the early bound entity classes that gets generated to also generate an extra "Text" property for OptionSetValue properties that calls the above line, so my entity would have this added to it:
public string New_MyOptionSetText {
return this.GetFormattedAttributeValue("new_myoptionset"); // this is a protected method on the Entity class itself...
}
Could you utilize the CrmServiceUtil extension that will generate enums for your OptionSets and then add your new_myOptionSetText property to a partial class that compares the int value to the enums and returns the enum string
Again, I think specifically for this case, getting CrmSvcUtil.exe to generate the code you want is a great idea, but more generally, you can access the property name via reflection using an approach similar to the accepted answer # workarounds for nameof() operator in C#: typesafe databinding.
var textValue = entity.FormattedValues["new_myoptionset"];
// becomes
var textValue = entity.FormattedValues
[
// renamed the class from Nameof to NameOf
NameOf(Xrm.MyEntity).Property(x => x.new_MyOptionSet).ToLower()
];
The latest version of the CRM Early Bound Generator includes a Fields struct that that contains the field names. This allows accessing the FormattedValues to be as simple as this:
var textValue = entity.FormattedValues[MyEntity.Fields.new_MyOptionSet];
You could create a new property via an interface for the CrmSvcUtil, but that's a lot of work for a fairly simple call, and I don't think it justifies creating additional properties.