Entity Framework, database wide Guid table, insert order - c#

We have a synchronization framework that uses a global SyncEntity table to keep track of which entities have been updated at what time, meaning we have a global table with a structure something like this:
<dbo.SyncEntity>
ID int
EntityType int
EntityGuid uniqueidentifier
The EntityType is an enum that corresponds to the specific entity so that we know in which table to look for this entity.
All our tables have an ID (PK) and a GUID.
I have created a Foreign Key constraint from the different Entity tables and to the EntityGuid in the SyncEntity table.
This works perfect for existing data however when we use EntityFramework to insert new data it doesnt insert the data in the "correct" order resulting in an error because the SyncEntity with the required EntityGuid is not yet inserted.
I guess we could add a property SyncEntity on all of our entities however i really dont want to pollute our domain model with that property.
So my question, is there anyway to ensure that specific Entity types are inserted as the first entities?
Or is there anyway to map the relation from Guid (on the specific Entity) to EntityGuid (on SyncEntity) without a navigation property.

I see two ways you could potentially alleviate this issue.
First, you could use domain events to recognize that a new entity has been created and raise an event, passing in the entity itself as a parameter and then allow that event to create a new SyncEntity insert it and then save it. This will populate your ID and then you can assign it to the new entity creating the relationship.
Second, you could override the SaveChanges method of the DbContext to look at added entities and then create a new record for each of them, then assign your new SyncEntity Ids to the entity.

WHy would you bother EF with something like that?
Have the SyncEntity entry created by a trigger on the tables. Finished. EF does not have to bother with it.
And it is save for direct SQL usage, too.
EF is a good tool - though only a very very mediocre ORM. But it is not a solution for everything. DB internal logic, like a logging table, should be handled in the database.

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

Entity Framework Navigation Property for a field that can store a foreign key from two different tables

I need a table called Loan.
The columns of this table will be:
Id, Type, BorrowId, Description
The trick here is that Type field will determine whether the borrower is an Employee or a Customer and then the BorrowerId will either be an Id from the Employee table or an Id from the Customer table.
Is this bad design as far as Entity Framework is concerned? The reason I ask is because it seems like I won't be able to create a Borrower Navigation property on the Loan table since the Id can be from two tables.
Does anyone have a solution for this? Like how I can change my data models to work with Navigation properties.
A simple answer to your question is "Yes it's a bad design". Referential Integrity should be strictly enforced and when you remove that ability by alternating the reference you create a window for errors. If you want two options create two columns, and create foreign keys on each to the tables they reference. Then your application will be effectively foolproof. :D

MVC : Insert data to two tables

I have two tables wherein i want to insert the data to the first one (MASTER) and the other table would copy some of the data from the Master table..
Here is my representation:
I want the Ven_ID to also be reflected in my Workflow table Workflow_ReqID automatically.
I know this is possible but can someone give me the directions ?
You can have a trigger/procedure at database level which will insert data into your second table. It depends if this table is updated anywhere else.
There are two ways to go about it :
Use SQL Server AFTER INSERT Trigger. You can find plenty of resources off the internet on how to create a trigger and how to declare its definition.
Another way to do it is through entity framework (I see you have tagged entityframework)
I will explain how you can use entity framework
Let's say you have the entity representing the WorkFlow table as WorkFlow and the table representing Ven (may be vendor) as Vendor.
Since you are having required foreign key in the WorkFlow table of the Vendor primary key, you must have a backing stub for that i.e. your WorkFlow table must have a virtual navigational property of type Vendor i.e.
public class WorkFlow
{
//other properties
public virtual Vendor Vendor{get;set;}
}
you just have to create WorkFlow object and the Vendor object (either create a new or retreive from db) and just assign it to the workflow object i.e.
WorkFlowObj.Vendor = objVendor
and EntityFramework will take care of rest.
I would prefer this way.
Though using triggers is not bad, but only problem with them is when you have to deploy, you must also deploy them triggers and every time you make changes to them, you must take care of them too.
If you want Ven_ID and Workflow_ReqID to be same get the Vent_ID in the output parameter in store procedure and pass it to the second table insert statement.
Get last inserted id using SCOPE_IDENTITY() after insertion and add it to workflow table. To save db trip you can use sproc for that.

DbContext with read-only set properties

I was reading this article http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-2-connections-and-models.aspx and was trying to figure out how to create private setters (the section in the article DbContext with read-only set properties is right before the summary). How would you create private setters? I was playing around with different methods but nothing seemed to work. I am doing this because I need to group the original table based on a query I have because the original table is a heap and I need a primary key for the entity. So anytime a client asks for this table it is already grouped. Not even sure if this is the correct way to do that. Thanks.
EDIT: sorry for being vague. I am doing code first. For example there exists a SQL Table with JobNbr, Qty and Date and I need to group by JobNumber, sum on Qty and take the oldest expiration date, and that will be my entity since this table has no primary key. The way I am doing it now gives me the error below from a method I created in the DbContext class. I do have a EntityTypeConfiguration class. Do I do this in that class?
EDIT: : you might be wondering why I am doing this. Basically I need to get data from the heap and save it in another database. My original approach was database.SqlQuery() to get grouped rows from the heap, but sometimes I have too many parameters for execute_sql. So I decided to create an entity for the grouped query without tracking changes (since all I am doing is reading from the table and saving to another DB). See my post here with the issue I am having https://stackoverflow.com/questions/22106030/entity-framework-6-this-database-sqlquery-character-limitation-with-sp-executes. The only way I know to get around it is to create an entity (even though in this case the entity is a query and not a table).
The entity or complex type
' cannot be
constructed in a LINQ to Entities query.

Prevent the loading of subclass table rows in TPT inheritance on Entity Framework

I have the following table hierarchy in my database which i map to an Entity Framework model (Database First) using the Table-Per-Type (TPT) inheritance pattern:
The mapping in the EF model is straightforward: AssetContent is a base abstract class while the other 2 are concrete subclasses.
The AssetContent table participates into a many-to-many relationship with another table which, to keep the picture clear, is omitted.
My question is, how do i build a Linq-to-Entities query to load the related AssetContent table using Include() such that the 2 'sub-tables' are not loaded at all? This is especially important for the DatabaseAssetContent table, whose BinaryContent field may be quite large and of no relevance to the issuer of the query i want to build. As far as i observed, Entity Framework automatically loads the entire hierarchy for a table, whether lazy loading is enabled or not, but i am interested in loading only the rows in the AssetContent table.
Is such a query possible using Linq-to-Entities (for Entity Framework 6)?
Eventually, i moved the AssetContent table's fields (except the Id) into another, new table, called AssetContentWithMetadata, which has a 1-1 relationship to the AssetContent table. This way, the AssetContent table remains indeed a bit awkward, with a single field (the ID), but now i can load the metadata table alone, without burdening it with the contents as well.

Categories