How to use Composite Keys with DAL2 in DNN 7+? - c#

I am working with DAL2 in DNN 7+.
I have a database table with a primary key created from 2-varchar(50) fields.
What is the proper way to declare the multi-field primary key in the attributes of the object?
I typically do:
[PrimaryKey("myField")]
Should I just add a second PrimaryKey attribute?
The second part of the question is how to get the data out of the database.
I would like to use the GetById() function because it incorporates caching but it doesn't appear to support multiple fields. Am I stuck using the Find() method and handling caching manually or what is the best way to select objects that use a multiple field primary keys?
"Look to the sky as much as the screen!"

DAL2 does not support Composite Keys.
The best way I have found to work around this limitation is to modify the database table. I use an Auto-increment int 'id' field for the primary key and set a unique constraint on the fields that I desired to use as the composite key.
This will required the .Find() method to be used which prevents caching. If caching is desired it must be done manually. When cache is manually set, it should be manually cleared as well. If you are using the repository technique make sure to clear the cache when the object is updated, or deleted.
"Look to the sky as much as the screen!"

Related

Include primary key of reference table in model using NHibernate

We are using NHibernate for DB operations and in our database there is a reference of Organisation in the Configuration table. This is existing code and cannot be changed.
Configuration table is heavily used throughout application so we want to include the OrganisationId in the Configuration model class, but not in table as it already has reference object. By doing this we will avoid loading whole organisation object when we just need OrganisationId.
//Configuration.hbm.xml
<many-to-one name="Organisation"
class="Organisation"
not-null="false"
foreign-key="FK_ConfigurationItem_Organisation"
unique-key="UniqueConfigurationItemName"/>
//Configuration.cs (Model Class)
public virtual Organisation Organisation { get; set; }
How do I modify hbm or model class so that we get organisationId without including this field in table?
I am new to NHibernate and stuck with this requirement.
Any suggestion will be appreciated.
Thanks
it should not be necessary to try this optimization manually, because NHibernate has multiple options to handle that on it's own, and that methods work especially well for heavily used object (aka. rows). If you use a session-object with a cache NHibernate will prefere to access the cache (aka. memory) and not load from the database (a second, third or ... time). If you use eager or join-loading then NHibernate will include simple foreigen keys in the first sql to the database, a much quicker way then lazy-loading (only bad if he foreigen key is never accessed).
BUT
This is a bit of a guess and I am not 100% sure that it is the intended way to do it, but I accidentally mapped a column twice and you could do that too for the organisation, once as a foreigen key and once as a simple column (of witch ever type organisationid is).
Make sure that the setter of the "simple column" property is not public!
Make sure to update the "simple column" in the setter of the foreign key.
Greetings
Juy Juka

How to add a new entity marked with [DatabaseGenerated(DatabaseGeneratedOption.None)]

We have an entity, Role, marked with the attribute [DatabaseGenerated(DatabaseGeneratedOption.None)]. So far we have used seeding to seed the entities into the database. But now we want to create a new page to let users add/update roles. What is the right way to add new such entities to the database? Does Entity Framework does it automatically? Or do I first need to get the max id (a simple int column) and set it on the new entity? If so, is it safe, in terms of concurrency? Is there a right way to be concurrecy safe?
If you seed the data using the SqlBulkCopy class, you can use the database-auto-generated ids, allowing you to use the best of both worlds (this is also more efficient if you are seeding a lot of data).
Is there a right way to be concurrency safe?
Since you explicitly state
[DatabaseGenerated(DatabaseGeneratedOption.None)]
You disable the concurrency safe database-auto-generated Id's (primary keys/identity).
So your options are:
enable database generated id's
use natural keys
spend a lot of time creating a system that behaves like the database-auto-generated id's.
Another thing you could do is just change the PK to a uniqueidentifier instead, but if you have FKs off this, then that wouldn't work very well. Then you could just create a new guid for an insert and not worry about it. (#Daniel Lorenz's suggestion, see comment)
The entity framework is not really of much help here.
Maybe you can elaborate why the database generated id's are disabled.

Entity Framework 6.1.1 - Programmatically set ID when StoreGenerated is Identity

I am at the early stages of building a new application. I am using EF6.1.1, most of my tables have a uniqueidentifier column and I have set StoreGenerated = Identity.
When I create new records they are assigned a new Guid and it all works fine.
For testing/debugging purposes I have written code to write some of the tables to an XML file. When I import this file EF still generates a new Guid.
In this case only I don’t want EF to do generate a new Guid. I want to preserve the original Guids as not doing so would break foreign keys. I have set StoreGenerated = None and this solves the problem but it seems very inelegant and it would require me to manually create all the Guids.
I need to persuade EF to let me set the Guid in this one case. Is there a way to change the StoreGenerated property at runtime?
You can't change the StoreGenerated property value at runtime (or - in fact - any EF metadata). You need to decide whether you want to insert your keys or have database generate them and EF will play accordingly. GUIDs are kind of easy because even if you generate keys on the client you don't have to expose it - for instance you can always assign a key value in the constructor and have EF overwrite it for entities it materializes from the database. You could even make the key setter private to not let anyone else set the value.

Entity Framework 5 Key naming with code first

I can't have [.] (periods) in my key names (Indexes, primary keys and foreign keys) when they are generated by Add-Migration, so I tried to write a CSharpMigrationCodeGenerator, but unfortunately this doesn't seem to allow you to change the foreign keys or index names. The primary key name can be set as part of overriding the create table:
protected override void Generate(
CreateTableOperation createTableOperation, IndentedTextWriter writer)
{
createTableOperation.PrimaryKey.Name = "USE THIS NAME";
base.Generate(createTableOperation, writer);
}
But what I really need is a way to ensure that it has just removed full stop (which implies overriding the custom name generator) - but I can't see how to do this.
Have you not tried retrospectively generating code first with the power tools?
Not only would it generate code first classes for you from the database, you can also customize the T4 templates that generate your objects in order to handle unique scenarios (for example custom naming logic to handle reserved characters). My entity.tt has the following above each generated object:-
[MetadataType(typeof(<#= efHost.EntityType.Name #>_Validation))]
This means I can have all my data validation farmed off into a separate class that isn't overridden upon re-creation of my objects.
this issue no longer exists and was quite specific at the time. Things have moved on with tooling over the last year and therefore isn't really relevant anymore as you wouldn't need to solve the issue this way.
Many thanks for reading and commenting
by entity framework code first migration you can change the foreign keys or index names, you can see in the example in here:
http://msdn.microsoft.com/en-us/data/jj591621.aspx
http://www.dotnetcurry.com/showarticle.aspx?ID=889

decoupled generic key-value access against linq in a non-xml environment

good morning.
i am not a computer scientist by education, so please overlook any shady term abuse.
in my framework, a base form called Record opens form RecordDetail as dialog. for example, RecordClient extends Record and contains client data and tabbed lists of client-relevant child data, and RecordDetail expands one child data row for detailed editing based wholly on reflection and display overrides stored as custom attributes used against DataContext. Record is subclassed for the application, but i see no need to subclass RecordDetail. this works except for the display of foreign key edits in the listed children.
i must use ObjectListView and Linq; i cannot use WPF/XML. because i do the serialization trick for non-continuous database connectivity, i lose foreign key objects when i clone data to manage state. ObjectListView needs the foreign key object for display and general wickedness. i know Hibernate, but Linq leaves me at a loss:
how might i access the foreign key object from within Record after its dialog to RecordDetail closes - without coupling framework and application-specific classes?
that is,
Type rowType = row.GetType();
IDomain workDamnit = (IDomain)dataContextReflectedFromRowType.GetTable(rowType).Where(x => x.PrimaryKey == 1).SingleOrDefault();
where "PrimaryKey" wraps the primary key attribute, and the fail happens between "GetTable", "Where" and "SingleOrDefault".
any perspective appreciated on this fine sunday morning.
actually, i've decided to uncle under and cache the foreign key objects in a pool accessed by the subclassed Record forms.

Categories