Custom Identity Types in Mapping - oracle

I have an application where the identity column is stored as an Oracle VARCHAR2(50 BYTE) but is actually a Guid. I want my model to expose it as a Guid:
class Foo
{
public Guid Id { get; set; }
}
Using Fluent NHibernate I don't see a CustomTypeIs() method on the IIdentityPart. I would think it would be something similar to an IUserType, but I can't find the correlation. Any thoughts?

Fabio Maulo noted that this is governed by the DataProvider on the NHibernate Users mailing list.

Related

How to Auto Generate of Guid ID in .NET CORE 6?

In my request data, if I have a duplication Guid ID, I want to generate a new Guid ID automatically. How to do it?
public class Roster { public Guid Id {get; set;} }
Here Guid Id is the primary key.
When I made an api post request, what would be the value I give for Guid Id?
If you use SQL and EntityFramework Core you could use this inside your model:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ActivityId { get; set; }
This will tell EF:
this property is the PRIMARY KEY of the table hence the [KEY]
this property should be automatically generated by the database
FYI you need to set a DEFAULT value for you SQL column like so:
(newsequentiaid()) tells SQL that he's in charge of creating a Globally Unique Id everytime you add a record to that table
Don't know if this is the answer you were looking for (nex time provide more info for us) anyway
hope this helps you Cheers!
UPDATE
I do not know if my solution works with MySQL i use it for SQL. Searching a bit online i found no resources to newsequentialid in MySQL database (but i could be wrong, do your own research if you'd like).
Anyway i just don't set it for example:
var activityDB = await context.Activity.FirstOrDefaultAsync(c => c.ActivityId == activity.ActivityId);
if (activityDB == null)
{
activityDB = new Activity();
context.Activity.Add(activityDB);
}
activityDB.Code = activity.Code;
activityDB.Description = activity.Description;
activityDB.Status = activity.Status;
Here's what the code does
check if my id exists if yes i have to edit if is null i don't
create new activity and edit
automatically EF nows what id to handle therefore no need to se it
If there is it means im editing for that id if not will create it automatically

How to Authenticate using MVC5RC/RTW with existing database

I originally asked this question when Identity was in beta. The classes and interfaces have changed considerably since then and it appears the RTW version has some modifications again over the RC version. In principle I need to achieve the following.
authenticate the local login against my usertable tblMembers which contains the userid field and password which are the two items I need to authenticate.
have access to my tblMember record/class via the Controller.User property (Prior to MVC5 identity I had achieved this using the membership provider methods.) regardless of if the user logged in via the localuser method or via one of the other OAuth providers (Twitter, Google etc).
Ability to display my own custom username despite the login method. Local users login with a userid 1234567 and a password, ideally I would like to display "John Smith (1234567)" regardless of the authentication method (local/Twitter etc)
Initially I'm unsure as to what my memberclass should be inheriting from It appears from the
aspIdentitySample project that I should be using IdentityUser?
public partial class tblMember
{
public int id { get; set; }
public string membership_id { get; set; }
public string password { get; set; }
....other fields
}
Are there any new or updated examples of integrating your existing database/user tables with the ASP.NET Identity system?
I am also adding the identity tables to my database. If you create a new web project in visual studio 2013 you will see that now in RTM everything works better than RC plus you will see the
following table
public class ApplicationUser : IdentityUser
{
}
So Instead of ApplicationUser you can call your table tblMembers
public class tblMembers : IdentityUser
{
}
your table tblMembers will inherit Id Username Password security stamp and a discriminator column saying this is a tblMemeber
without making custom classes for authentication the easiest thing to do would be just to make the username the combination of your old usernames and userids. Then store the users real name or old username without the user id in a separate column.
have the users register with the built in user login and they can go to manage account and click use another service to log in. This will link the Google account to their regular account, so no matter which one they use it will log them in to the same account. If you have users with connected table information, I suggest you seed your table with all the users with something similar to the register method found in the template.Then just match the new combined username and Id to the old ones and populate data where needed in sql management studio.
Again a lot of issues in RC with extending IdentityUsers have been fixed. Microsoft is already adding more features to the identity user store and this tutorial http://www.windowsazure.com/en-us/develop/net/tutorials/web-site-with-sql-database/ is supposed to be updated soon. I plan on making my own walk through when i'm done changing my database but for now I hope my suggestions even though they are a simpler solution than you might want to implement.
You can do this easily by modifying the IdentityModel.cs as per the below:
Override OnModelCreating in your DbContext then add the following, this will change AspNetUser table to "Users" you can also change the field names the default Id column will become User_Id.
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
or simply the below if you want to keep all the standard column names:
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo")
Full example below (this should be in your IdentityModel.cs file) i changed my ApplicationUser class to be called User.
public class User : IdentityUser
{
public string PasswordOld { get; set; }
public DateTime DateCreated { get; set; }
public bool Activated { get; set; }
public bool UserRole { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<User>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
modelBuilder.Entity<User>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
}
}
Please note i have not managed to get this working if the current table exists.
Also note whatever columns you do not map the default ones will be created.
Hope that helps.
I'm starting to think (partially due to the lack of information in this area), that it may be easier to user the default identity classes, but to provide referential integrity to my own user table from the AspNetUsers table.
If i add a custom linking field into the AspNetUsers table is it possible to access my tables from the Controllers.User property? i.e. Controller.User.tblMember.Orders?

Programmatically Change Database Table EntityFramework Model Object Refers to

Question is in the title. Can we programmatically change the database table which an object in the Model class, like one below, refers to and continue to operate on the new table?
public class Word
{
public int ID { get; set; }
public string Text { get; set; }
}
This originally refers to "Words" table automatically in EntityFramework, is there a way to change it before/during runtime? If so, how?
EDIT:
I get all the string used in Views in the project from the database table, "Words", by their ID's. Now, what I want is, a user enters a new language to system, and a new table will be created, for example WordsEnglish. From then, the Word object will refer to WordEnglish, if user selects English as language.
It would be desirable with a use case to better understand what you are trying to accomplish, but here goes...
In the DbContext.OnModelCreating method you can configure the model, e.g.
// Removes pluralization convention for all tables.
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
or
// Specific table name for Word Entity.
modelBuilder.Entity<Word>().ToTable("TableContainingWords");
If you are changing your model, Code First Migrations might be what you need.
I havent found a way to truly dynamically extend an EF model at runtime. Given what goes on in DB context inherited class, the use of generated views for performance and a model class approach, avoiding recompilation seems hard. I have generated code, compiled and access this using assembly discovery approaches. But this is all unsatisfactory from my viewpoint , so i have stopped investigating this path. Very clunky outcome.
Ironically the topic you provide as a use case for such a problem, is one that doesnt need dynamic EF in my view.
I have exactly the same use case, language specific look for messages/labels etc Ie a language specific textpool.
Why not add language to the class/table.
Use a table or Enum for supported languages.
Use Language in the Textpool table/s
Use a different model class for presentation. (view model).
So you can present it the way like .
public class Word
{
Guid ID {get;set;} // logical key is WordID + Language
public int WordID { get; set; } // implement with new id or 2 field key
public Language Language {get;set;} // see cultureInfo for more details
public bool IsMaster {get;set;}
public string Text { get; set; } // consider renaming due to reserved word implications
}
public class language
{
int ID,
String Lang
}
}

what DataAnnotation to make an SQL Identity column?

I have the following in my class and need to know how to modify the DataAnnotation to make it an identity column
public class Item
{
public Int16 ItemID { get; set; }
}
The goal is to have the EF5.0 equivalant of the SQL
ItemID smallint IDENTITY(0,1) NOT NULL,
You can use DatabaseGenerated attribute with DatabaseGeneratedOption.Identity. You can find more details about configuring EF with attributes here http://msdn.microsoft.com/en-us/data/jj591583 and about DatabaseGnerationOption enum here:
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.databasegeneratedoption.aspx. You can also configure your model with Fluent API - here are some examples http://msdn.microsoft.com/en-us/data/jj591617

Defining a one-to-one-or-zero relationship in Entity Framework with Code First

I know there are a lot of questions around on this subject, but I've not managed to find one that actually explains how to solve my particular problem. Which I suppose means that it might be insoluble (I think it might be 'backwards' to EF's way of thinking), but I have to ask.
I have a model with three (abbreviated) POCOs as so:
[Table("People")]
public class Person {
public int PersonID { get; set; }
[Required]
public string PersonName { get; set; }
}
public class Location {
public int LocationID { get; set; }
public int LocationTypeID { get; set; }
public virtual LocationType LocationType { get; set; }
}
public class Van : Location {
public int PartyID { get; set; }
public virtual Party Party { get; set; }
}
These are backed by (abbreviated) database tables (we write these by hand):
CREATE TABLE People (
PersonID INTEGER IDENTITY NOT NULL,
PersonName VARCHAR(255) NOT NULL,
PRIMARY KEY (PersonID)
)
CREATE TABLE Locations (
LocationID INTEGER IDENTITY NOT NULL,
LocationTypeID INTEGER NOT NULL,
FOREIGN KEY (LocationTypeID) REFERENCES LocationTypes(LocationTypeID)
)
CREATE TABLE Vans (
LocationID INTEGER NOT NULL,
PersonID INTEGER NOT NULL,
PRIMARY KEY (LocationID),
FOREIGN KEY (LocationID) REFERENCES Locations(LocationID),
FOREIGN KEY (PersonID) REFERENCES People(PersonID)
)
You can probably imagine what LocationTypes looks like.
Locations is the root of a table-per-type hierarchy - there are also check constraints in place to enforce this. Vans are a kind of location, as are other things irrelevant here like Warehouse.
Now, a Van belongs to a Person, in that we issue a van to an employee and it's their responsibility to fill it up with fuel, not crash it, take it to customer sites and order more stuff when they've used up all their supply of screws, drill bits and armoured DC cable. However, not every Person has a van (some of them work in pairs in one van), and the Person table doesn't have a foreign key which points to the Van - it's the other way around. This is in some sense a historical accident, but it models the situation quite neatly because while a Person doesn't have to have a Van, a Van most assuredly has to have a person.
So to my question: how do I get Person to have a navigation property with their Van in it?
public virtual Van Van { get; set; }
I've done a lot of playing around with data annotations and the fluent API, and the closest I've got is this in OnModelCreating:
modelBuilder.Entity<Van>()
.HasRequired(v => v.Person)
.WithOptional(p => p.Van);
Unfortunately this tries to populate the Van property with a proxy that yields a Location object. It might even be the right Location object (I haven't been able to check), but it's not realised that it should be looking for vans. I do suspect, however, that it might be trying to match PersonID against LocationID when it does the lookup - without the Fluent API mapping, I just get no vans at all, which is what I'd expect (all PersonID values are lower than the lowest LocationID values which correspond to vans so couldn't possibly find anything).
This would no doubt be quite easy if Person had a nullable foreign key to Van, but then we'd have foreign keys in both directions, and if we took the one out of Van then we'd not be modelling the absolutely essential constraint that a Van has a Person.
So, I suppose, Van owns this relationship, and the Van property on Person is an inverse navigation property, but it seems EF isn't very good at this kind of trick with one-to-ones even if one end is optional. Is there a way to make it work, or do I have to accept a compromise?
We generally refuse to compromise the database model for the sake of Entity Framework's missing features. What I really need is a way to tell EF that the Van property on Person can be populated by joining to Vans on Vans.PersonID = Person.PersonID.
The problem is that this is at the moment not supported. You mentioned that you didn't managed to find any question where would be your problem solved. I wonder if you find any question mentioning that EF doesn't support unique constraints / candidate key which is absolutely necessary to solve this type of one-to-one relations.
In database one-to-one relation can be achieved only if FK in dependent table is unique. This can be done by two ways: placing unique constraint (index) on FK column in dependent table or using PK in dependent table as FK to principal table.
EF enforces same rules for referential integrity as database but in case of one-to-one relationships and lack of support for unique constraint it doesn't support the former way. EF can model one-to-one relationship only by using PK of dependent table as FK to principal table.
You can vote for support of Unique constraints / candidate keys on Data UserVoice.
How to solve your particular issue? By cheating EF. Let EF think that you have one-to-many relation and place unique constraint on PersonID in Van table. Than update your Person like this:
[Table("People")]
public class Person {
public int PersonID { get; set; }
[Required]
public string PersonName { get; set; }
public virtual ICollection<Van> Vans { get; set; }
[NotMapped]
public Van Van
{
get { return Vans.FirstOrDefault(); }
set
{
Vans.Clear();
if (value != null)
{
Vans.Add(value);
}
}
}
}
It is pretty ugly workaround because Vans collection is still public. You can play with its visibility but make sure you understand few things:
Once Vans is not public you must map it in OnModelCreating and for that context must be able to see the property or you must provide mapping configuration which does that. Check this and this for some more information.
Vans property must not break rules for proxy creation to support lazy loading
Eager loading must use Vans property

Resources