Ok, so I have 2 entities: Course and Industry
The industry entity is just a reference table which lists all available Industries that can be tagged to a course, to categorizing them. I put in a many to zero or one relationship (a course can choose to have an industry or not, while an industry can be tagged with many courses).
I know I've played around with the diagrams a bit, adding and removing associations in the past.
Now here is the odd part: The column mappings for Course has 2 similar columns, IndustryId and Industry_Id
I suspect it's from a past association, but thought EF would have taken care of that.
Here is the problem:
In my view that creates the course, the IndustryId is the property which needs to be populated. When I create new courses, I see the IndustryId in the database populated.
However, when I access Industry's properties through Course (Course.Industry.Description) nothing is populated. It can't seem to get the Industry entity.
I see the IndustryId populated in the db, so I tried to populate the Industry_Id column. That fixed it.
Weird enough, the property declared in the model is IndustryId, so that column is populated in the db. But when I try to get Industry entities through Course, it needs the Industry_Id, which I don't quite know where it is from.
Anyone have any ideas?
It sounds like in your updating from the database, you changed the column name on your tables from Industry_Id to IndustryId. The next time you updated from the database, EF5 (which can't determine that this is the same column, as it matches on names) dropped the mapping for Industry_Id, and added a new column called IndustryId.
However, you had already created the foreign-key mapping in your EDMX file based on the Industry_Id column - which is why you get the issue around needing it when loading related records.
In general, when using Database-First, whenever you rename a column in the database, you need to update your EF5 model and update / correct any such discrepancies.
Related
I have an ASP.NET Core application that uses EF6 for dealing with a third-party application's database.
Everything is working as expected, but I'm unable to insert rows into a joining table.
I have two tables, Users and Groups, and a joining table GroupUser that identifies which users are members of which groups. Users has a PK of UserId, and Groups has a PK of GroupId.
GroupUser has only 3 columns: GroupId, UserId and another column (which is irrelevant for this post). The two foreign keys in this table identify a unique record.
Every time I try to insert into GroupUser, I get the inner exception
The table/view does not have a primary key defined. The entity is read-only
The error is correct. There is no PK, but both of the FKs are marked as keys in the model. Shouldn't VS be able to use those as a PK somehow?
The inserts used to work as some point, but required some manual modification of the .edmx file as XML in order to work. Unfortunately, our version control records containing this modification have been lost (and I wasn't the one originally working on this).
I've looked at and tried about a dozen articles around this, but they generally have to do with views instead of tables, so don't seem applicable to my case. The ones that did seem applicable didn't solve the issue.
The only other clue I have for a solution is this comment I found in the code:
// Important note: If you have updated the edmx file in the [redacted]
// project and suddenly start having problems, the edmx file may need to be
// edited as an xml file so that you can make changes necessary to make
// VS believe that the GroupUser table has a primary key. See revision #[redacted]
I'm able to insert into User and Group tables just fine, and as I've said, I don't have access to the revision log mentioned.
Edit: The database is for a third-party application, and unfortunately, it's not as simple as just modifying the table to add a PK. I wish it was. Problem would be solved. But I've been advised by the vendor not to make this change, as it may have unexpected consequences, and would void our support.
How can I 'trick' EF into thinking the table has a key? I'm also open to other workarounds. Modifying the DB structure is currently out of the question.
Context:
I have a data model in Power pivot with three tables, tTasks, tCaseworks and tCaseworkStatus. I am attempting to create two calculated columns in tCaseworks which from the two data tables. All three tables are linked through the common field casework_id (see illustration below).
The data model is regularly updated with new data. The way I am doing this is as follows:
All three tables are sourced from three corresponding tables in my Excel workbook.
A VBA script deletes all records in the three Excel tables and then refreshes the data model (sidenote: because the data model demands lookup tables to not be empty the VBA code adds one row per table before refreshing).
New data is then added to the excel tables and the data model is refreshed.
This process works perfectly.
Problem:
The problem arises when I am adding calculated columns to tCaseworks and then attempting to update the data as described above. I have added two calculated columns; has_task and status_now. I am using the following DAX code:
has_task:
has_task =
IF (
CONTAINS (
RELATEDTABLE ( tTasks );
tTasks[casework_id]; tCaseworks[casework_id]
);
"Yes";
"No"
)
status_now:
status_now =
VAR TableX = RELATEDTABLE(tCaseworkStatus)
VAR ResultX = IF(
CONTAINS(TableX;tCaseworkStatus[casework_status_code];"Completed");"Completed";
IF(CONTAINS(TableX;tCaseworkStatus[casework_status_code];"Dismissed");"Dismissed";
IF(CONTAINS(TableX;tCaseworkStatus[casework_status_code];"Begun");"Begun";
IF(CONTAINS(TableX;tCaseworkStatus[casework_status_code];"Created");"Created";
"Find no status"))))
RETURN
ResultX
Both of these calculated columns work as expected as long as I do not delete the data in the model (I do have one hickup with both columns as described in this separated problem, but I think that is unrelated).
When the data has been deleted and I refresh the model I get the following error message:
"We cannot get the data from the data model. This is the error message we got: A circular dependency was discovered: 'tCaseworks'[status_now],'tCaseworks'[status_now],'tCaseworks'[has_task],'tCaseworks'[has_task],'tCaseworks'[status_now]."
Question:
What is creating this dependency and how can I avoid it?
My attempted solutions:
The problem only arise when there are two of these calculated columns. Any one of these two works perfectly without the other upon refreshing. I know that calculated columns are prone to circular problems, but unfortunately I need to use columns and not measures. I suspect that perhaps my choice in formula is creating the problem, most likely the contains-function. However, I don't know about any alternative ways of building the formulas I need. Any suggestions?
Edit:
I originally only posted a portion of my data model as I wanted the question to be as concise as possible but I guess it might have been confusing. The whole model concerns five objects from a case handling system: Claims, Cases, Caseworks, Tasks and Action Points. These objects are hierarchical, one claim can have one or more cases, but one case can only have one claim. Similarly, a case can have several caseworks, a casework can have several tasks, a task can have several action points. Additionally, the latter four can have a status attribute which is changed regularly.
I attempted to organize my data model in such a way that I had a lookup table for each object with unique values. I have many attributes for each object in my data that I did not include in the example above, and my goal was to add useful attributes through calculated columns in these tables. The data tables with the changes were intented to provide insight to the lookup tables.
I think your relationship model is a bit unusual. DAX works best when using something like dimensional fact model
I would consider the tCaseworkStatus a fact table since its like a log of the changes to your data. tTasks is a dimension, since it just add an extra dimension to your data.
The tCaseworks is not necessary since it doesn't hold any actual data (only calculated data).
if you want your current model to work, it might fix your problem if you just delete the relationship between tTasks and tCaseworks, and add a new between tTasks and tCaseworksStatus
edit.
it just occurred to me that the reason you have it like this, is that you may have a many-to-many relationship between tTasks and tCaseworksStatus. if that is the case you might have to create a proper many-to-many table. which is kind of what your tCaseworks is, but you cant have a relationship to the same key like you currently have.
edit2.
the solution seemed to be that somehow the Relatedtable function in conjunction with the relationship model was causing the error. using Lookupvalue instead seems to to have fixed the issue.
I have an application with a dataset linked to an sql server database. I have updated some of the names or foreign keys and primary keys in the sql server. How do I make those changes translate to the data set. For example, I had a primary key called fk_temsempl_xxxxx. I changed it to fk_temsempl on the sql database. How do I get that change to show in the dataset designer in visual studio?
I have tried running custom tool by right clicking on the dataset and clicking run custom tool. That didnt work. I tried configuring the table adapter of one of the tables where a change occured, but the name of the relation didnt change.
You actually just right click the relation and choose Edit Relation... or double click on the line (when the mouse cursor changes from arrow to drag symbol) but I honestly wouldn't bother; you'll then have further refactoring to do in the code anywhere the relation is used, and it can be heavily used by visual designers.
You also get the problem that VS may not help you with the refactoring: in data binding scenarios most things that can be a source of data can also be a collection of multiple things that can be a valid DataSource. They then rely on a string DataMember to determine which of the collections of data in the data source should be used for the data.
For example, when a bindingsource is bound to list a DataTable, the bindingsource.DataSource property might be the DataSet object that contains the DataTable, and thebindingsource.DataMemberis a string of "YOUR_TABLE_NAME". the BindingSource might not be bound asmyBindignSource.DataSource = myDataSet.MyDataTable`. Refactoring inside strings involves a find and replace
DataRelations in a DataSet are created from foreign keys as they were discovered when the relevant table(s) were added to the dataset but it is important to note that, like DataTables and everything else, they are NOTHING to do with the database schema objects at all - they aren't permanently associated with them, the dataset entities are just set up looking something like the database objects when they (dataset entities) are first created. DataTables are created from only those columns selected, and whatever .NET datatypes closely resemble the types output by the query. For a table of:
Person
------
Name VARCHAR(50)
SSN INTEGER
Birthdate DATE
If you created the table with SELECT * FROM Person you'd get a datatable with Name (string), SSN (int), Birthdate (datetime) but if you made a new datatable in the dataset based on SELECT LEFT(Name, 1) as Initial, PADLEFT(SSN, 20) as PadSSN, DATEDIFF(day, Birthdate, NOW()) as AgeDays FROM Person then you'd get a datatable of Initial (string), PadSSN (string), AgeDays (int) - i.e. the datatable looks nothing like the db table. This concept of disconnection between dataset and db is pervasive, and really the only things that relate in any way to the database are the properties that specify which DB table/column a particular DataTable/DataColumn relates to for purposes of loading/saving data. Your Person.Name datacolumn can be renamed to Blahblah, but it will still have a .SourceColumn property that is set to "Name" - that's how the mapping between dataset and db works; dataset is predominantly completely independent of the db. Renaming a DB column would require a change to the SourceColumn property only
DataRelations don't even have this notion of linking to the parent relation in the database; there's no SourceRelation or SourceFK proeprty because there is no need to. They're set up with the same rules and a generated name all based on the rules of the FK, but then they function independently and only within the dataset. If you rename or even remove an FK from the db the dataset will carry on working in the same restricted way it always did; adding a datarow to a child table when no aprent row exists for it will throw an exception - none of it anything to do with the FK in the db, and the DataRelation can have different rules to the FK (e.g it can cascade deletes when the FK is NOACTION) or even different columns. You can have more or fewer DataRelations than the DB has FKs
Run Custom Tool is not a "contact the DB and see what changes have occurred there and replicate them into the dataset", it is a "turn the XSD that describes the dataset into a bunch of C# classes that implement strongly typed dataset/table/relation/column etc objects". Any time you change the XSD by making an edit in the visual designer and hit save, the custom tool is run. If you edit the XSD directly in a text editor you may need to run it manually to have your changes reflected in c# classes
Reconfiguring a tableadapter probably won't do anything to the relations either; its solely concerned with changing the datatable and tableadapter. If you really want to refresh the relations, delete the datatable from the set and recreate it. Be prepared for a potentially significant mop up/refactoring of code
I have problems to refresh the structure of a table in my universe.
We have added some data to a reference table which is used in universe. After checking the new data in (Oracle 11g) database, found everything OK.
Then opened up designer in BO, imported the universe, looked up the associated table which only shows the existing items (not the new ones) - which seemed ok for me. I clicked on "View"/"Regenerate structure" but BO says that the structure does not need to be regenerated?
I have no idea what goes wrong and how I can add the new items to the table in my universe. Or do I have to update the content of a table differently?
It's possible that Designer isn't properly reading the database's data dictionary, and therefore not seeing the new column.
Data fields do not have to be present in the model in Designer in order for objects to reference them. So I would create a new universe object that references one of the new fields, and parse it. If it parses, then the field really is there and Designer just isn't seeing it. However if it doesn't work (i.e., you get an "invalid identifier"-type error), then the field is not there.
Joe's answer gave me the hint to check again why the new fields have not been there. And finally I found it. My "table" was a view which had to be actualized (SQL-select statement) and after that I could pick up the data into my universe and as shown in reports. Now everything is fine.
I am just getting into Entity Framework for the first time beyond simple examples.
I am using the model-first approach and am querying the data source with LINQ-to-Entities.
I have created an entity model that I am exposing as an OData service against a database where I do not control the schema. In my model, I have two entities that are based off of two views in this database. I've created an association between the two entities. Both views have a column with the same name.
I am getting the error:
Ambiguous column name 'columnname'. Could not use view or function 'viewname' because of binding errors.
If I was writing the SQL statement myself, I'd qualify one of the column names with an alias to prevent this issue. EF apparently isn't doing that. How do I fix this, short of changing the view? (which I cannot do) I think this does have something to do with these entities being mapped to views, instead of being mapped to actual tables.
Assuming you can change the model have you tried going into the model and just changing one of the column names? I can still see how it might be problematic if the two views are pulling back the same column from the same table. I can tell that when working directly with a model mapped to tables, having identically named columns is not a problem. Even having multiple associations to the same table is handled correctly, the Navigation Properties are automatically given unique names. Depending on which version of EF you used you should be able to dig into the cs file either under the model or under the t4 template file and see what's going on. Then you can always create a partial class to bend it to your will.