Entity Framework foreign key default value - sql-server

I have tables Users and Roles.
In Users table I have default value for RoleId column.
But I don't how I can make it work in EF4, for example, if I set RoleId property as DatabaseGeneratedOption.Computed
_repository.Save(new User()
{
Login = "asdasd",
Name = "sadqwqwd",
Password = "wqdwqd"
});
new user will be insert with default value, but if I want set RoleId in code
_repository.Save(new User()
{
Login = "qqasdasd",
Name = "qqsadqwqwd",
Password = "qqwqdwqd",
RoleId = 2
});
it will ignore my RoleId value and set again default value.
If I remove DatabaseGeneratedOption.Computed option I cant insert user object wihtout RoleId value.
How I can resolve this problem? Thanks in advance.

Properties with DatabaseGeneratedOption.Computed option will be ignored by EF in insert/update operations and can be set on database side only.
Remove DatabaseGeneratedOption.Computed option from RoleId property and set default value in the constructor of User class.

Related

"Invalid field for upsert, must be an External Id custom or standard indexed field: Name" error

I am trying to enter unique values to the Contact object. Here is the code:
List<Contact> conList = new List<Contact> {
new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
new Contact()};
// Caroline Roth already exists so I want this code to update her record, not insert another Caroline Roth record
Database.UpsertResult[] srList = Database.upsert(conList, Contact.Fields.Name, false);
Salesforce's documentation states
"The upsert statement matches the sObjects with existing records by comparing values of one field. If you don’t specify a field when calling this statement, the upsert statement uses the sObject’s ID to match the sObject with existing records in Salesforce. Alternatively, you can specify a field to use for matching. For custom objects, specify a custom field marked as external ID. For standard objects, you can specify any field that has the idLookup property set to true. For example, the Email field of Contact or User has the idLookup property set."
I have two questions:
1) how can we see which fields on the Contact object have their idLookup property set to true
2) why am I getting the error in the subject line when I execute the code?
1:
Map<String, Schema.SObjectField> contacFieldsMap = Schema.getGlobalDescribe().get('Contact').getDescribe().fields.getMap();
for (Schema.SObjectField field : contacFieldsMap.values()) {
Schema.DescribeFieldResult fieldResult = field.getDescribe();
if (fieldResult.isIdLookup()) System.debug(fieldResult.getName() + ' IS idLookup');
}
2: System.debug(Contact.Name.getDescribe().isIdLookup()); // false

I need to get the user id from my users table in DynamoDB?

I'm using AWS Amplify on my react native app
I want to do something seemingly so simple, but i am a bit lost as to how to do it: I have a table with user information already in it. Here's the Schema:
type Users #model {
id: ID!
userName: String
firstname: String
weblink: String
email: String
mobileNum: String
.
.
.
}
//Here's my Query.js
export const getUsers = `query GetUsers($id: ID!) {
getUsers(id: $id) {
id
userName
firstname
weblink
email
.
.
.
}
}
`;
This table is populated in DynamoDB when i check my AWS console. What i need is to be able to get the id from the table using the userName (not vice versa). The id is generated when i createUser() and it's used throughout my app to get all my user's information. However when a user signs in on a new phone, this id isn't available anymore. So when they sign in via Cognito, i do know the userName and all i need to do is retrieve this id.
Normally i would do this, but obviously i want to do the reverse and use my unique userName to get the id:
const userData = await API.graphql(graphqlOperation(GetUsers, { id: usersId })); //usersId = "3b0dae-24j5-4401-95a6-11seyhaf1g131"
Any idea how i can get my users id?
Assuming that the userName is unique, create a Global Secondary Index with userName as the partition key. Project, at least, the id attribute into the index. Finally, search that index instead of the underlying table.
Alternatively, if you never need to lookup by id, consider making userName the partition key and id a regular attribute.

How can I assigned roles automatically in webmatrix

I want to assigned new registered users automatically the role of Member in Database.
WebMatrix sample Starter Site app - Account\Register.cshtml
Tested and it works.
// Check if user already exists
var user = db.QuerySingle("SELECT Email FROM UserProfile WHERE LOWER(Email) = LOWER(#0)", email);
if (user == null) {
// Insert email into the profile table
db.Execute("INSERT INTO UserProfile (Email) VALUES (#0)", email);
//Roles have already been added to webpages_Roles table
//Logic to determine role for e-mail (user) being added for the first time
if (email == "John#gmail.com") {
var userName=email;
var roleName="Administrator";
Roles.AddUserToRole(userName, roleName);
}
else if (email == "Greg#gmail.com") {
var userName=email;
var roleName="Guest";
Roles.AddUserToRole(userName, roleName);
}
else {
//All others are assigned the role of Member
var username=email;
var roleName="Member";
Roles.AddUserToRole(userName, roleName);
}
In your register code, which in the sample WebMatrix app is found in the file Account\Register.cshtml, there's if statements that first determine that the information being submitted is valid and then that the email doesn't exist in your database. Within those if statements, if the user is successfully created, then you can add code like:
// boy, is this a hack, Member = RoleID 8
db.Execute("INSERT INTO webpages_UsersInRoles (UserId, RoleID) VALUES( #0, 8 )", UserID);
Now I used 8 as an example. Look in your webpages_Roles table. This has a list of RoleNames and their RoleID. If you've already created the Member role, it will be in this table. Use the corresponding RoleID instead of the 8 that I used.

Get the ID in a child entity of NDB GAE Datastore

I'm going in circles on getting the id of NDB Datastore.
I have setup the webapp2.RequestHandler to catch the email and get the ID. Basically my goal is to delete an entity, but if I pass the email address to get the ID of the entity, I'm stump, because it gives me results I was just getting. I used ID instead of key_name.
I tried finding the ID by querying via email, but it seems like using query does not have a method attribute to find the id.
def get(self,email):
user = users.get_current_user()
if user:
user_key = ndb.Key('UserPrefs',user.email())
contacts = Contact.query(Contact.email==email,ancestor=user_key)
self.response.write(contacts.id) # there is no attribute such as Contact.id
I tried to find the ID by getting the key, but when I displayed the key, it showed me whatever value I have in the email variable
def get(self,email):
user = users.get_current_user()
if user:
user_key = ndb.Key('UserPrefs',user.email())
contact_key = ndb.Key('Contact',email,parent=user_key)
self.response.write(contact_key.id())
Real Question: So, given that I do not have the ID, how do I find the correct ID inside an entity if I saved my entities via id and not key_name?
Here are the mixture of codes that I'm trying out.
def get(self,email):
user = users.get_current_user()
if user:
user_key = ndb.Key('UserPrefs',user.email())
contact_key = ndb.Key('Contact',email,parent=user_key)
contacts = Contact.query(Contact.email==email,ancestor=user_key)
contact = contacts.get()
contact_key.delete()
# self.response.write(contact.name) # this works
self.response.write(contact_key.id()) # this does not work because I do not have the entity id, and I'd like to get it blindfolded. Is there a way?
Here is my Model for Contact.
class Contact(ndb.Model):
name = ndb.StringProperty()
phone = ndb.StringProperty()
email = ndb.StringProperty()
dateCreated = ndb.DateTimeProperty(auto_now_add=True)
dateUpdated = ndb.DateTimeProperty(auto_now=True)
The docs state:
The identifier may be either a key "name" string assigned by the application or an integer numeric ID generated automatically by the Datastore.
Since you are defining the name property on your Contact class, this is used as the identifier. (You don't want that because in real world different users can have same names)
So if you want NDB to generate numeric IDs for your entities, rename the name property to something else, e.g. username.
Update: let's go step by step:
Problem with the first example is that you are trying to get id on the Query. Query class has no id property defined on it. You should call get() on it:
# get() or fetch() should be called on query to return some data
contacts = Contact.query(Contact.email==email,ancestor=user_key).get()
self.response.write(contacts.id) # there is no attribute such as Contact.id
Problem with the second piece of code is that you are just initialising a Key and providing email as id - the second param of constructor is the id and you are providing email as value. Hence you are getting the email out. Also, there is no database operation here.
Note: the identifiers, which are id, key, urlsafe, or value (for the query) should be passed from the HTTP Request by webapp2.RequestHandler from a parsed url or HTTP POST, GET, PUT, or DELETE.
If you do not have any identifiers or values passed from an HTTP request, it could be difficult to access the specific entity (or the record). So, it is important to take note to pass a form of identifier or value to access the specific entity (or the record in database terms).
So, you can do the following to get the id:
Access by value:
def get(self,email):
user = users.get_current_user()
if user:
user_key = ndb.Key('UserPrefs',user.email())
contacts = Contact.query(Contact.email==email,ancestor=user_key)
contact = contacts.get()
id = contact.key.id() # this access the entity id directly because you have the data.
self.response.write(id)
Access by urlsafe:
def get(self,urlString):
user = users.get_current_user()
if user:
contact_key = ndb.Key(urlsafe=urlString) #urlString refers to the key of contact
contact = contact_key.get()
id = contact.key.id() # this access the entity id directly because you have the data.
self.response.write(id)
Access by HTTP POST Request:
def post(self):
user = users.get_current_user()
if user:
user_key = ndb.Key('UserPrefs',user.email())
email = self.request.get('email')
contacts = Contact.query(Contact.email==email,ancestor=user_key)
contact = contacts.get()
id = contact.key.id() # this access the entity id directly because you have the data.
self.response.write(id)

How Can I Automatically Populate SQLAlchemy Database Fields? (Flask-SQLAlchemy)

I've got a simple User model, defined like so:
# models.py
from datetime import datetime
from myapp import db
class User(db.Model):
id = db.Column(db.Integer(), primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
date_updated = db.Column(db.DateTime())
def __init__(self, email, password, date_updated=None):
self.email = email
self.password = password
self.date_updated = datetime.utcnow()
When I create a new User object, my date_updated field gets set to the current time. What I'd like to do is make it so that whenever I save changes to my User object my date_updated field is set to the current time automatically.
I've scoured the documentation, but for the life of me I can't seem to find any references to this. I'm very new to SQLAlchemy, so I really have no prior experience to draw from.
Would love some feedback, thank you.
Just add server_default or default argument to the column fields:
created_on = db.Column(db.DateTime, server_default=db.func.now())
updated_on = db.Column(db.DateTime, server_default=db.func.now(), server_onupdate=db.func.now())
I prefer the {created,updated}_on column names. ;)
SQLAlchemy docs about column insert/update defaults.
[Edit]: Updated code to use server_default arguments in the code.
[Edit 2]: Replaced onupdate with server_onupdate arguments.
date_created = db.Column(db.DateTime, default=db.func.current_timestamp())
date_modified = db.Column(db.DateTime, default=db.func.current_timestamp(),
onupdate=db.func.current_timestamp())

Resources