I would like to ask about inserting new record into table through entity framework. I have composited primary key (id and department_id). Department_Id is constant because there are departments and each department can create new record. Each record is replicated to all departments. Id is identity by department. But it cannot be identity on column because when all departments can create record with Id=1 but department_id will be different.
Now I solve it that I create new record in dummy table which has identity column and I get this value into Id column and save record. So for each table I have specialized table with identity column to generated Id value.
Table Customer (Id int, Department_Id int, …) Id, Department_Id is primary key.
Table CustomerIdentity(Id int identity(1,1), Dummy int null).
I have stored procedure to save new record:
declare #id int
declare #department_id int = 10 -- constant for department 10
insert into CustomerIdentity(Dummy) values (null)
set #id = scope_identity()
insert into Customer(Id, Department_Id, …) values (#id, #department_id, …)
I refactor this code to extract logic from stored procedure to C# where I have Customer entity. Id cannot be identity because there could be records as:
Id | Department_Id
1 | 1 -- record from department 1.
1 | 2 -- record from department 2.
1 | N -- record from department N.
So there is Identity table which holds identity value for each department. Each record from department 1..N is replicated to all departments.
How to set EF to give value for Id column from another table?
To do something with EF I would look at something like:
using (var context = new MyDbContext())
{
var customerIdentity = new CustomerIdentity();
context.CustomerIdentities.Add(customerIdentity);
context.SaveChanges();
var newCustomer = new Customer
{
DepartmentId = _DepartmentId, // I.e. "10"
CustomerId = customerIdentity.CustomerId
// ...
}
// Optionally you could delete the CustomerIdentity record.
context.CustomerIdentities.Remove(customerIdentity);
context.SaveChanges();
}
This assumes that each department will have its own database which would manage its own identity tables for the ids, but would be synchronized with other databases or a central database where data cross departments would be queried. The CustomerIdentity provides the sequence (autoincrement) for the IDs, so once that is retrieved (first SaveChanges call) and earmarked into the Customer record, the CustomerIdentity record can be deleted. The table would remain empty but the Identity would continue to increment. If you decide to keep the CustomerIdentity row you would want to avoid associating the Customer and CustomerIdentity entities in a relationship in EF even though for a department they would form a 1 to 1 relationship. Other departments identity counters could be higher and such a relationship would result in errors if the target database had identity up to say 50, and a record wants to get added with an ID of 65. Identity 65 doesn't yet exist so EF would throw a FK violation if you try to bring that customer record in.
Related
I have two tables, a query, and a form and I can't get it to behave like I want. There is a relationship between Table 1 and Table 2 formed between Employee ID (Table 1) and Employee (Table 2)
Employees (Table 1)
Employee ID (Key)
Employee Name
Status
Attendance (Table 2)
Attendance ID (Key)
Employee
Date
Note
Employee Query
Returns Employee ID and Employee Name for any employee with Status="Active"
Attendance Form (This form is used to enter records into Table 2)
Attendance ID (Table 2)
Employee (Drop down list from Employee Query)
Date
Note
Essentially what I want is for the form to work like so:
Dropdown to display Employee names that are "Active"
Save Employee ID back to Table 2
Display Employee name rather than ID in the form
The issue that I'm having is that the form wants to display the Employee ID rather than the name. This isn't practical for data entry but I still want the form to send the Employee ID to the table so we can run queries and reports.
Advise not to use spaces in naming convention.
Set combobox properties like:
ControlSource: Employee
ColumnCount: 2
ColumnWidths: 0";1"
BoundColumn: 1
RowSource: SELECT EmployeeID, EmployeeName AS FullName FROM Employees ORDER BY EmployeeName WHERE Status = 'Active';
This will display name but save id.
Employee name parts really should be in separate fields: FirstName, MiddleName, LastName. Then RowSource like:
SELECT EmployeeID, LastName & ", " & FirstName & " " & MiddleName AS FullName FROM Employees WHERE Status='Active';
I have a table which contains a employee ID and a database ID code in database DBX0 table 'FirstTable':
Employee ID
Database ID
123
1
456
2
789
2
149
3
The database name is stored in a different table 'databases' like :
Database ID
DB name
1
DBX1
2
DBX2
3
DBX3
So what I'm trying to do is join the first table with a separate table which is stored in the identified database, like
SELECT * from DBX0.dbo.FirstTable a join (SELECT [DB name] from DBX0.dbo.databases where [database ID] = a.[database ID]).dbo.OtherTable
(I don't think this will actually work with a subquery, but this would return the result that I want in theory.)
I have tried dynamic sql with a cursor to iterate through each database and then only return results based on database ID = database ID and Employee ID = Employee ID, but this returns the results in a separate result per database.
Also tried:
Select * from (SELECT * from DBX0.dbo.FirstTable a join '+#dbname+'.dbo.OtherTable on a.employeeid = b.employeeid and a.dbid = b.dbid)
in dynamic sql, but this didn't work either.
Is there any way to get all of the data in one result?
I have to insert data to db in form fields that have the same path and i want to save it different id's but rather it concatenated it with ",", how could i possibly do it?
I tried to make some alias in SQL but it saves into same db field name with concatenated with ","
i expected in db when i insert that
EX.
db field name = description
input 1 value = "john";
input 2 value = "doe";
id description
1 john
2 doe
above is my expected result
but in my case when i insert it shows these
id description
1 john,doe
can someone help me to achieve that result ? THANKYOU!
Let me present a similar situation. You have a database of people and you are concerned that each person might have multiple phone numbers.
CREATE TABLE Persons (
person_id INT UNSIGNED AUTO_INCREMENT,
...
PRIMARY KEY(person_id) );
CREATE TABLE PhoneNumbers (
person_id INT UNSIGNED,
phone VARCHAR(20) CHARACTER SET ascii,
type ENUM('unknown', 'cell', 'home', 'work'),
PRIMARY KEY(person_id, phone) );
The table PhoneNumbers has a "many-to-1" relationship between phone numbers and persons. (It does not care if two persons share the same number.)
SELECT ...
GROUP CONCAT(pn.phone) AS phone_numbers,
...
FROM Persons AS p
LEFT JOIN PhoneNumbers AS pn USING(person_id)
...;
will deliver a commalist of phone numbers (eg: 123-456-7890,333-444-5555) for each person being selected. Because of the LEFT, it will deliver NULL in case a person has no associated phones.
To address your other question: It is not practical to split a commalist into the components.
i am trying to do the folowing:
1) create or replace type transaction as object (date Date, description
varchar(30));
create or replace type T_transaction as table of transaction;
2) create or replace type account as object (id int, description varchar(30),
t_transaction T_transaction)
nested table t_transaction store as xxx1;
create or replace type T_account as table of account;
3) create or replace type user as object (id int, descr varchar(30), t_account
T_account)
nested table t_account store as xxx2;
create or replace type T_user as table of user;
4) create or replace table banks (name varchar(20), users T_user)
nested table users store as xxx3;
first 2 types were created successfully, but "create or replace type account..." is giving -> Warning: Type created with compilation errors.
is there an advice for creating such database using multiple level of nested tables ?
Edit:
I did some research on the subject (object nesting limitations) and here are my findings:
According to Database Limits,
every column of a nested table is in effect added to the columns of the host table and the maximum total number of columns in a table is 1000.
So this would be the official upper limit (in case every nested table had a single column).
However, when I did actual testing (on 11g and 12c), I weren't able to create a table with a nesting depth more than 50 because of error
ORA-00036: maximum number of recursive SQL levels (50) exceeded.
Thus I conclude that the maximum possible depth of nesting is 50.
Initial answer:
I am not aware of limits on objects nesting but I think they should be reasonably permissive.
Your code fails because you made a few mistakes:
1. Using type names as column names (date, t_account, etc.);
2. Using nested table clause in a wrong place;
The code should go like this:
create or replace type transaction_type as object (tx_date Date, description varchar2(30));
create or replace type transaction_tab as table of transaction_type;
create or replace type account_type as object (id int, description varchar(30),
transactions transaction_tab);
create or replace type account_tab as table of account_type;
create or replace type user_type as object (id int, descr varchar(30), accounts account_tab);
create or replace type user_tab as table of user_type;
CREATE table banks (name varchar(20), users user_tab)
nested table users store as xxx3 (
nested table accounts store as xxx2 (
nested table transactions store as xxx1
));
Checking
INSERT INTO banks VALUES (
'John', user_tab(
user_type(1
,'regular user'
, account_tab(
account_type(1
,'regular account'
, transaction_tab(transaction_type(
trunc(sysdate)
, 'regular transaction'))
))
)));
SQL> SELECT *FROM banks;
NAME
--------------------
USERS(ID, DESCR, ACCOUNTS(ID, DESCRIPTION, TRANSACTIONS(TX_DATE, DESCRIPTION)))
--------------------------------------------------------------------------------
John
USER_TAB(USER_TYPE(1, 'regular user', ACCOUNT_TAB(ACCOUNT_TYPE(1, 'regular accou
nt', TRANSACTION_TAB(TRANSACTION_TYPE('04-APR-18', 'regular transaction'))))))
Selecting nested table columns
SELECT b.name, u.id, u.descr, a.id, a.description
FROM banks b, table(b.users) u, table(u.accounts) a
WHERE u.descr = 'regular user' AND a.description = 'regular account'
NAME ID DESCR ID DESCRIPTION
----- --- ------------- --- ----------------
John 1 regular user 1 regular account
I have recently started using Entity Framework and have run into a problem.
I have 2 simple tables mapped with Entity Framework in my solution:
Employees:
emp_id INT
first_name VARCHAR
last_name VARCHAR
department INT ( FOREIGN KEY MAPPED TO departments.dept_id )
and
Departments:
dept_id INT
department_name VARCHAR
Using the code below, I want to write to the database.
var record = db.employees.Create();
string test = "test";
record.first_name = test;
record.last_name = test;
record.department = 1;
db.employees.Add(record);
db.SaveChanges();
I get an error the error:
Entities in "'DBContextContainer.employees' participate in the 'employeedepartment' relationship. 0 related 'department' were found. 1 'department' is expected."
at the db.SaveChanges() method. Can someone please explain to me how I could resolve or troubleshoot this?
Update: There is a record in the departments table with a dept_id of 1 and I am still getting the error.
You'll need to add a field to the Departments table first since Departments is the parent table (Employees depend on Departments as per your table structure). You cant add an employee with department that doesn't have a corresponding entry in the Departments table.