On any change to a dbml via the graphical interface (add a table/stored proc) every reference to System.Int32 gets changed to System.[Integer] (square brackets included) causing hundreds of errors.
This is manifest everywhere in this dbml designer.vb such as:
Public Property ArghID() As System.[Integer]
Public Function PleaseHelpDetails(.... <Global.System.Data.Linq.Mapping.ParameterAttribute(Name:="WhyWhyWhyID", DbType:="Int")> ByVal WhyWhyWhyID As System.[Integer], ...
Private _AnnoyanceID As System.[Integer]
Partial Private Sub OnHauntedDbmlIDChanging(value As System.[Integer])
I can find no references to this. Can anyone speculate as to the cause?
A search and replace fixes this, but it is a complete nuisance.
Update: Having Tried the classic "delete the appropriate "*AppData\Local\Temp\Temporary ASP.NET Files* folders" trick - with no luck.
Took a look at the SVN history of the file - and some IDs were set up as bytes(!) - and those were changed to integers at some point, manually. I am looking for some inconsistency with this - but can't find anything yet.
So there it is - search and replace had search and destroyed the dbml.
The definition of the table columns were set up like this in the dbml file:
<Column Name="WellObviouslyID" Type="System.Integer" DbType="Int NOT NULL" CanBeNull="false" />
instead of
<Column Name="WellObviouslyID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
and forced their integrity on the other occurrences in the .designer page.
It was a poor choice in replacing strings that led to this. As ever, avoidable by doing things via the gui. Trying to save time is always perilous.
Related
I'm creating a reusable workflow in SharePoint designer 2010. I've created a custom content type with all the necessary fields that I'll be used in the workflow. But I'm not able to get the Modified By field (Editor) inside the workflow.
<FieldRef ID="{d31655d1-1d5b-4511-95a1-7a09e9b75bf2}" ReadOnly="TRUE" Name="Editor" DisplayName="Last Updated By" FromBaseType="TRUE" Required="FALSE" PITarget="" PrimaryPITarget="" PIAttribute="" PrimaryPIAttribute="" Aggregation="" Node="" />
I really doubt whether the ID is matching with the inbuilt editor field. How can I cross-verify this? Any ideas?
Not sure but do you really need to include it explicitly? Editor is part of base content type : Item, and down the hierarchy all other content types should be inheriting it without the need to explicitly include it.
Regards,
Nitin Rastogi
Visual studio is giving me a trail of errors that I have hit a dead end on. I am trying to add an existing table in a database to my data model. I understand that the table should have a key, but it doesn't and I can't fix that; it isn't my database to re-design.
When I first try to add the table, I get this error:
The table/view
'BT8_GC.dbo.SAVED_QUERY_CATEGORY' does
not have a primary key defined and no
valid primary key could be inferred.
This table/view has been excluded. To
use the entity, you will need to
review your schema, add the correct
keys, and uncomment it.
Ok, fine, I'll define the keys for it and uncomment. Here is the block I uncomment, after manually defining the keys (I also had to add the nullable=false part):
<EntityType Name="SAVED_QUERY_CATEGORY">
<Key>
<PropertyRef Name="SQC_CAT_ID"/>
<PropertyRef Name="SQC_USER_ID"/>
</Key>
<Property Name="SQC_CAT_ID" Type="int" Nullable="false" />
<Property Name="SQC_USER_ID" Type="int" Nullable="false" />
<Property Name="SQC_CAT_DSCR" Type="varchar" MaxLength="50" />
<Property Name="SQC_SEQ_NO" Type="int" />
</EntityType>
Nope, now the designer won't open. Go back into the file, and Intellisense shows this error:
Error 11002: Entity Type 'SAVED_QUERY_CATEGORY' has no entity set.
Ok... Uncommenting created a new error. After adding an entity set:
<EntitySet Name="SAVED_QUERY_CATEGORY" EntityType="IssueModel.Store.SAVED_QUERY_CATEGORY" store:Type="Tables" Schema="dbo" />
Yay! The designer opens! Still not there yet, because while it shows up under the store's Tables/Views folder, it has not Entity Type in the model. Can't call it from my code. I don't have any errors to work off though, so I tried creating an entity set mapping, but that results in the error "does not exist in MetadataWorkspace".
So that's what I have tried. How do I get this poorly designed table into my data model?
By modifying XML you have only added information about database table. Now you have to open toolbox and add entity to your model in the designer. Configure the entity to have properties as you need. Then open mapping details and map the new entity to your table.
Btw. once you modify the XML describing database manually you cannot use update from database anymore - VS designer will always delete your changes and you will have to do them again.
I have a solution that was created with NHib 1.2 which we're upgrading to NHib 3.0.
Our hbm file has the following property:
<property name="ContentId" column="ContentId" access="field.camelcase-underscore" />
The class doesn't have a ContentId property. This was working fine in NHib 1.2 but now we're getting getting the following exception:
Could not compile the mapping document: XXXX.Core.Domain.Video.hbm.xml ---> NHibernate.MappingException: Problem trying to set property type by reflection ---> NHibernate.MappingException: class Core.Domain.Video, Core, Version=1.0.0.29283, Culture=neutral, PublicKeyToken=null not found while looking for property: ContentId ---> NHibernate.PropertyNotFoundException: Could not find the property 'ContentId', associated to the field '_contentId', in class 'Core.Domain.Video'.
Why would this stop working? Is it still supported in NHib 3?
We have many many properties like this that we might need to add.
NHibernate greatly improved its error messaging and diagnostics in NH2.X and again in NH3.X. You are telling NHibernate that you have a property and you want to map it via field access to a field named by _camelCase convention. You don't have a property named ContentId and NHibernate is letting you know that you lied to it. :)
Try updating your mapping to:
<property name="_contentId" column="ContentId" access="field" />
You will need to update any HQL or Criteria queries to use _contentId rather than ContentId. Another option would be to add a private ContentId property.
I'd like to provide information which helped me answer this question:
http://groups.google.com/group/nhusers/browse_thread/thread/e078734a221c3c0c/ec8b873b385d4426?lnk=gst&q=field+camelcase+underscore#ec8b873b385d4426
In this link Fabio explains the same problem you are having like this:
This mapping
<property name="PositiveValue" access="field.camelcase-underscore" />
mean: For my property named "PositiveValue" you (NH) have to access to
the field; to discover which is the associated field you (NH) have to
use the strategy "camelcase-underscore".
If there is no property you can't use the accessor with a specific
strategy.
Which struck me as a little odd because it meant adding dummy, unused properties, just to make the nhibernate3 compiler happy. The underlying functionality is the same.
VB .NET 4 WinForms application.
I have a (DevExpress) grid bound to an IEnumerable(Of MyClass).
Whenever a new row is added, the ID defaults to zero (0). On trying to SaveChanges, EntityFramework doesn't realise that being an identity field means it should ignore any contents on insert and just insert the other values. I can't specify null / Nothing because it just keeps the ID as zero.
I can add and save instances of MyClass manually, but I'm trying to get it to work where the grid handles adding/initialising/etc new entries. As far as I can tell, the problem is not with the grid but with Entity Framework and the generated SQL and entity classes.
{"Cannot insert explicit value for identity column in table 'MyClasses' when IDENTITY_INSERT is set to OFF."}
Any assistance to prevent me from throwing my laptop out a window would be greatly appreciated!
If a property of an Entity is an Identity (auto-incrementing value) in the database is specified in the StorageModel of your Entity Model. Perhaps this setting is not correct for your particular field. You can check this by opening the edmx file of your model and looking into the StorageModels section. It should look like this:
<edmx:StorageModels>
...
<EntityType Name="MyClass">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="..." Nullable="..." StoreGeneratedPattern="Identity" />
...
</EntityType>
...
</edmx:StorageModels>
StoreGeneratedPattern must be set to Identity. If there is None or the attribute is missing (which defaults to None) you get indeed the error you described since EntityFramework doesn't know in this case that ID is an identity and will issue a value for the column in the generated SQL-INSERT statement.
(Make sure you are really checking the edmx:StorageModels section in the edmx file. The edmx:ConceptualModels section has an attribute annotation:StoreGeneratedPattern in the property as well but its setting doesn't matter for your specific problem. (I think that's only important when a database gets created from a model, but I'm not sure.))
Let's say my domain looks like this:
I have an object, Vehicle, that has an OdometerReading property.
An OdometerReading has the Miles & Date (when it was read).
I need to keep a history of all OdometerReadings for the Vehicle in the database, but don't want the entire odometer history to belong to the Vehicle object. What I would like is for the OdometerReading property map to the most recent OdometerReading entry out of the database.
I thought about mapping the whole collection of OdometerReadings to the Vehicle, and having a dynamic property called CurrentOdometerReading that would order them and return the latest one, but I don't need the whole collection under the Vehicle in my domain, and it seems like I would be getting more data out of the database than I need.
Is that possible with NHibernate? How would I map such a thing?
There are a few ways of doing this depending on what you want your domain model to look like. My preferred choice is to use a custom collection type, for example IOdometerReadingCollection, which you can add extra methods to. In this case it might be something like:
public interface IOdometerReadingCollection : IList<OdometerReading>
{
OdometerReading Latest { get; }
}
This way you can do:
OdometerReading reading = vehicle.OdometerReadings.Latest;
which I prefer to:
OdometerReading reading = vehicle.LatestOdometerReading;
There's lots of documentation about custom collections, which you can find with a simple google search.
If this approach isn't for you there are other options. You may be able to use a property with a formula (I'm not sure if that works with complex types?), or a regular NHibernate association where you'd have the key of the latest OdometerReading on your Vehicle mapping. As you also mentioned you could just load all the OdometerReadings, which depending on your use case might actually be fine.
I hope this helps, or at least points you in the right direction.
There is a "where" clause that you can put in your collection mapping. Check the reference documentation.
I would map the OdometerReading property as a component, then use a named query to ensure it's populated with the latest reading out of the database. (In this example, you'd have a sql-query with a name of "vehicle" that does the SQL to load the Vehicle columns along with the latest Odometer reading)
<class name="Vehicle">
<property name="Type" not-null="true"/>
<component name="OdometerReading">
<property name="Miles" />
<property name="Date" />
</component>
<loader query-ref="vehicle"/>
</class>