LINQ DeleteOnSubmit without Primary key - c#

I have the following code and I want to delete all rows from TABLE where the column 'id' IS NOT Primary Key.
#{
using (var db = new DataClassesDataContext())
{
var query = db.Table.Where(r => r.id == 2).ToList();
if (query != null)
{
foreach (var q in query)
{
db.Table.DeleteOnSubmit(q);
}
}
db.SubmitChanges();
}}
This throws a System.InvalidOperationException because the table has not Primary Key column.
How is it possible to do that without adding a primary key in the SQL Server database?
Thanks in advance

Open the LINQ Designer. Open the properties window for the table you want to delete a record from. Click on any of the columns in the entity you want to delete and you'll see a property labeled "Primary Key". Change the value to true for column you want to use as a primary key.
P/S:This will not set the primary key on your real table.

Related

Sorting Table with Foreign Key Columns

I have a Table(Geraete) in the View which also displays data from a Foreign Table by using the public Virtual Key Ort(Foreignkey to Table Orte) to access the other Table. This works fine, but my Problem is when i want to sort the Column of foreign Values the following Code snippet does not work:
//test.Sortcolumn(String Value of the Column name which should be sorted)
var pi = typeof(Geraete).GetProperty("test.SortColumn");
//movie.Typens is from Type List Geraete
movie.Typens = (from t in movie.Typens select t).OrderBy(x => pi.GetValue(x, null)).ToList();
And yes this Snippet works for Columns of the same Entity Type Geraete.
In the View the values of the foreign Tables are easily accessable by using Ort.Columnname but this does also not work with the Code snippet above.
If you want to traverse the navigation property it would be something like
x =>
{
var o = x.GetType().GetProperty("test",x);
var pi o.GetType().GetProperty("SortColumn");
retrun pi.GetValue("SortColumn",o);
}

To delete a row from a table of only foreign keys using Entity Framework

I have a table User { UserId, Name, Age } and License { LicenseId, Name, IsActive }. Also I have a table UserLicense { UserId, LicenseId } which connects both of these and has the record for all the users who hold a license. A user can hold multiple license and those appear as different rows in the UserLicense table.
Now I need to remove a particular license from the license table. I do not want to delete it outright, so I mark IsActive = false. However I do want to delete rows from the UserLicense table for that license Id.
I am using Entity Framework.
If it is a direct table, I would have done something like :
var lic = db.Licenses.Where(l => l.Id== licenseId).FirstorDefault();
db.Licenses.Remove(lic);
db.SaveChanges();
However since UserLicense is a table of foreign keys, Entity Framework does not allow me to access it directly using
public void DeleteLicensedUsers(Guid LicenseId)
{
db.UserLicenses.Where()
}
because the model does not contain an independent table for UserLicense as it is only a table of foreign keys.
So how do I delete all rows of UserLicense table for a particular licenseId using Linq and EF6?
If your entity class (I guess User), has navigation properties of type ICollection<Licence> by removing Licence from this collection you are actually removing items from UserLicense table. This is how Entity Framework handles many-to-many relationships in databases.
I faced a similar issue and you can solve it this way. I almost tend to avoid tables with just foreign keys and instead add another column to fix this issue.
var license = db.Licenses.Where(l => l.ID == LicenseId).FirstOrDefault();
var users = license.Users.ToList();
if (users != null)
{
foreach (var user in users)
{
license.Users.Remove(user);
}
}
I'm a little confused by your question. So if you mark a license as isActive = false, and still want to see that license appear on user's page, then there should still a record in UserLicense table associating the two.
That said, I believe this answer from a similar question will help you.
so essentially:
//include licenses in the user entity
var result = ctx.User.Include(x=>x.Licenses).Where(t=>t.Id == _id).FirstOrDefault()
//get the licenses you are looking for, either equal or use .Contains
var licensesOfUser = result.Where(x=>x.Licenses.Where(l=>l.id == _licenseId);
//remove them from entity and save.
result.Licenses.RemoveRange(licenseOfUser);
ctx.SaveChanges();
[edit: if you have license]
//include users in license entities
var result = ctx.License.Include(x=>x.Users).Where(t=>t.Id == _id).FirstOrDefault()
//get the users you are looking for, either equal or use .Contains
var usersOfLicenses = result.Where(x=>x.Users.Where(l=>l.id == _userId);
//remove them from entity and save.
result.Users.RemoveRange(licenseOfUser);
ctx.SaveChanges();

When add new model to database has error Cannot insert duplicate key

When i want add new model to DB
Violation of PRIMARY KEY constraint 'PK_dbo.Factors'. Cannot insert duplicate key in object 'dbo.Factors'. The duplicate key value is (1001).
The statement has been terminated.
My code :
var factor = new Factor();
factor.UserId = UserId;
Db.Factors.Add(factor);
Db.SaveChanges();
And model map:
In my design factor is must start whit 1000 and my code for this :
protected override void Seed(BreDbContext context)
{
context.Database.ExecuteSqlCommand("DBCC CHECKIDENT('Factors', RESEED, 1000);");
}
I Find solution.
Description for problem
When run below code in Migration Seed
context.Database.ExecuteSqlCommand("DBCC CHECKIDENT('Factors', RESEED, 1000);");
this code run per request and this code destroy database.
Remove this code and insert below code
protected override void Seed(BreDbContext context)
{
//context.Database.ExecuteSqlCommand("DBCC CHECKIDENT('Factors', RESEED, 1000);");
for (int i = 0; i < 999; i++)
{
context.factors.add(new factor());
}
context.savechanges();
var rang = context.factors.tolist();
context.factors.removerange(rang);
context.savechanges();
}
after create database comment all code in seed method.
best reference https://weblog.west-wind.com/posts/2013/Mar/26/Firing-an-Entity-Framework-Database-Initializer-from-within-DbContext
I think it's because u insert the value that has already in the PRIMARY KEY field which mean PRIMARY KEY value must be a unique value
For example u have a table with value :
id name
1 john
2 serah
3 crish
But after that you insert a new value:
3 victoria
in above case will throw an error because in the table already has a value with id = 3 (crish) // id field is unique (PRIMARY KEY)
OR
In other problem case if ur table has a relation with other table, if u want to insert a new value into FOREIGN KEY Table, u need to inserted first in PRIMARY KEY Table because FOREIGN KEY need to reference to PRIMARY KEY value.
I hope my answer helping u

Why is the unique constraint missing when filling the datatable?

I have the following table in SQL server
projects
id(PK, int, not null)
name (varchar(255), not null)
public_key_token (varchar(50), null)
I have added a unique constraint to the name column using
ALTER TABLE dbo.projects
ADD CONSTRAINT name_unique UNIQUE (name);
which results in a Unique, Non-Clustered index on the table (trusting SSMS).
In the code I'm retrieving the table data using
using (SqlDataAdapter adapter = new SqlDataAdapter("select * from " + DbTabName, con))
{
using (DataTable table = new DataTable(DbTabName))
{
DataTable dt = adapter.FillSchema(table, SchemaType.Source);
PkColumns = dt.PrimaryKey.Select(c => c.ColumnName).ToList();
AutoIncrementColumns = dt.PrimaryKey.Where(c => c.AutoIncrement).Select(c => c.ColumnName).ToList();
UniqueColumns = dt.Columns.Cast<DataColumn>().Where(c => c.Unique).Select(c => c.ColumnName).ToList();
...
}
}
The PKs and AutoIncrement columns are OK but in UniqueColumns I only get the PK column again.
The name column arrives in C# without the Unique constraint.
Changing the SchemaType to Mapped did not alter the result.
Why do I lose this constraint on the way to C#? Am I missing something on the SQL Server side or in C#?
[UPDATE]
#Tim-Schmelter's answer only solves the problem half way.
Just adding the index did not work. Also adding the index when the PK on the id column exists doesn't work.
The only way I got it to work was delete the table, recreate it without any key and indexes and then add the unique index as in Tim's answer. However, after adding the PK for the id column once more I'm back to the old behaviour that only the id is listed as unique column.
This is really weird.
Use this to create a unique index or use the the gui of SSMS.
CREATE UNIQUE NONCLUSTERED INDEX [name_unique] ON [dbo].[projects]
(
name ASC
)
You have added a unique constraint not a unique index.
Your code now successfully retrieves the UniqueColumns(the single column name).

on delete remove values with foreign key

I have two tables with foreign key relationship (1 to many). How can I do that when I'll remove item from first table, it will delete automatically all values with it's foreign key from second table?
So when I'll remove item from 1 table it will remove all items from 2 table whih NameId = ID of 1 table
Depends on the database management system; with MS SQL Server, you can set a foreign key to "ON DELETE CASCADE" which does exactly what you're asking for.
http://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php
You could just write a function for that:
public void RemoveWithRelatedEntries(int table1ItemID)
{
using(var db = new dbEntities())
{
// get all entities of table 2
var tab2Entities = db.table2.Where(tab2Ent=>tab2Ent.table1Reference == table1ItemID);
// remove all those entities
foreach(table2Item item in tab2Entities)
{
db.table2.Remove(item);
}
// finally remove entity from table 1
var table1entitiy = db.table1.Find(table1ItemID);
db.table1.Remove(table1entity);
db.Save();
}
}
there are probably more elegant solutions but this was what came first to my mind.

Categories