How can I delete all records from a table? - linq

I've been searching for an answer on how to delete ALL records from a table using LINQ method syntax but all answers do it based on an attribute.
I want to delete every single record from the databse.
The table looks like so:
public class Inventory
{
public int InventoryId { get; set; }
public string InventoryName { get; set; }
}
I'm not looking to delete records based on a specific name or id.
I want to delete ALL recods.
LINQ method syntax isn't a must, bt I do prefer it since it's easier to read.

To delete all data from DB table I recommend to use SQL:
Trancate Table <tableName>

Linq is not meant to change the source. There are no LINQ methods to delete or update any element from your input.
The only method to change you input, is to select the (identifiers of the )data that you want to delete in some collection, and then delete the items one by one in a foreach. It might be that your interface with the source collection already has a DeleteRange, in that case you don't have to do the foreach.
Alas you didn't mention what your table was: Is it a System.Data.DataTable? Or maybe an Entity Framework DbSet<...>? Any other commonly used class that represents a Table?
If you table class is a System.Data.DataTable, or implements ICollection, it should have a method Clear.
If your tabls is an entity framework DbSet<...>, then it depends on your Provider (the database management system that you use) whether you can use `Clear'. Usually you need to do the following:
using (var dbContext = new MyDbContext(...))
{
List<...> itemsToDelete = dbContext.MyTable.Where(...).ToList();
dbContext.MyTable.RemoveRange(itemsToDelete);
dbContext.SaveChanges();
}

Related

Servicestack Ormlite multi-column constraint fails where constraint includes Enum

I am using ServiceStack.Ormlite, and also make heavy use of the automatic handling of enums whereby they are stored in the db as strings but retrieved and parsed nicely back into Enums on retrieval, so I can do easy type-comparison - say, for a property "UserRole" in the db/table class "User" of enum type "UserRoleEnum" (just for demonstration).
This works great.. until I want to use the enum property to define a multi-column unique constraint
CompositeIndexAttribute(bool unique, params string[] fieldNames);
like:
[CompositeIndex(true, nameof(UserId), nameof(UserRole)]
public class User
{
public long UserId {get;set;}
public UserRoleEnum UserRole {get;set;
}
(as per :
How to Create Unique Constraint with Multiple Columns using ServiceStack.OrmLite? ).
At which time i get:
System.Data.SqlClient.SqlException
Column 'UserRole' in table 'User' is of a type that is invalid for use as a key column in an index.
I currently see options as:
a) Define UserRole as a string (isntead of UserRoleEnum ) in the table entity class and lose the Enum use.... having to manually test the value each time to confirm that the db value is one that i expect in my business logic later
b) Continue to use UserRoleEnum but lose the ability to declare multicolumn uniqueconstraints using the class attribute, and probably have to create these manually using a subsequent db migration script?
Is there any way to make the enums and the multicolumn constraint play nicely, out of the box?
This issue was because enum properties were using the default string definition fallback of VARCHAR(MAX) which SQL Server doesn't let you create indexes on whereas the column definition of a string property is VARCHAR(8000).
This issue is now resolved from this commit which now uses the VARCHAR(255) string definition of the EnumConverter Type Converter. This change is available from v4.5.5 that's now available on MyGet.
Otherwise you can also change the size of the column definition to match a string property by adding a [StringLength] attribute, e.g:
[CompositeIndex(true, nameof(UserId), nameof(UserRole))]
public class User
{
public long UserId { get; set; }
[StringLength(8000)]
public string UserRole { get; set; }
}

check if table has been created in code first approach

I am using Entity Framework's code-first approach to create tables, and I need to check if there are any entities in the database that I need to delete:
class MyDocument
{
public string Id { get; set; }
public string Text { get; set; }
}
class MyContext : DbContext
{
public DbSet<MyDocument> Documents { get; set; }
}
using (var data = new MyContext())
{
var present = from d in data.Documents
where d.Id == "some id" || d.Id == "other id"
select d;
// delete above documents
}
on first run, when there is no table yet, the LINQ expression above throws an exception:
Invalid object name 'dbo.Documents'
How do I check if the table is there and if it is not, then set present to the empty set, perhaps? Or maybe there is a way to force database/table creation before I issue the LINQ query?
EF will actually check the entire context against the DB it is attached to.
The DB can have more than the context. But not less.
So actually you check
Context.Database.CreateIfNotExists();
If the DB and context dont match and you are using automatic migrations, then you get specific object errors. But this can be misleading in terms of the how EF is handling the context to DB comparison.
You could of course try and access every DBSet in a context
Not sure how useful that is though.
EF Code first supports Migrations, either Automated or on demand.
See EF Code first migrations
Database.SetInitializer
use SetInitializer command to turn on automatic migrations for example.
The link will provide more info on the Manual/controlled approach to db migration for advanced db handling. The easier Automatic approach, is also described in the link.

Can't Persist Field to Aspnet_Users via NHibernate/ActiveRecord

I'm using ActiveRecord with NHibernate on the backend. I've set up a mapping for Users; I can create/retrieve/register users without any issues.
I now want to add an association called Role to my users (many users per role). I've created the appropriate Role class, tables, data, etc. and everything seems to be working on that end as well.
The problem is that when I save a user and associate a Role, that association does not persist to the database.
I've added a RoleId (int16) column to the aspnet_Users table to match the Role table's Id (int16) column. I've tried using Save and SaveAndFlush without success.
Here's some code:
Role superUser = Role.First(r => r.name == "Super User");
User me = User.First(r => r.UserName == myUserName);
me.Role = superUser;
me.Save(); // Or: SaveAndFlush
When debugging, I can see the association on the objects when they're saved (i.e. me.Role is not null and has the right attributes/properties/etc.) However, when I look at the database, the RoleId value for that user is still NULL. (SaveAndFlush doesn't make a difference.)
What am I missing?
I've read somewhere on SO that extending the users table is usually done by adding another table and linking the two by a foreign key; I assume the classes would then use inheritance by composition for the new ExtendedUser class. Assuming I don't want to go that route, why isn't this working? Is it because of the specific ASP.NET MVC stored procedures et. all?
Some relevant mapping:
[ActiveRecord("aspnet_Users", Mutable = false)]
public class User : ActiveRecordLinqBase<User>
{
[PrimaryKey(PrimaryKeyType.Assigned)]
public Guid UserId { get; set; }
// ...
[BelongsTo("RoleId", Cascade = CascadeEnum.SaveUpdate)]
public Role Role { get; set; }
}
[ActiveRecord]
public class Role : ActiveRecordLinqBase<Role>
{
[PrimaryKey]
public int Id { get; set; }
// ...
[HasMany(Inverse = true)]
public IList<User> Users { get; set; }
[Property]
public string Name { get; set; }
}
Edit: mutable="false" - this clearly stands that entity is read only, which is the source of your problem.
Immutable classes, mutable="false", may not be updated or deleted by the application. This allows NHibernate to make some minor
performance optimizations.
Also:
I believe that you need to have cascading defined. You are not saving just the entity itself but also reference to other entity. Use attributes, fluent config or hbml to define this the way you need. Here are the cascading options:
Here is what each cascade option means:
none - do not do any cascades, let the users handles them by
themselves.
save-update - when the object is saved/updated, check the assoications and save/update any object that require it (including
save/update the assoications in many-to-many scenario).
delete - when the object is deleted, delete all the objects in the assoication.
delete-orphan - when the object is deleted, delete all the objects in the assoication. In addition to that, when an object is
removed from the assoication and not assoicated with another object
(orphaned), also delete it.
all - when an object is save/update/delete, check the assoications and save/update/delete all the objects found.
all-delete-orphan - when an object is save/update/delete, check the assoications and save/update/delete all the objects found. In additional to that, when an object is removed from the assoication and not assoicated with another object (orphaned), also delete it.
You may want to read this article.

Extend SubSonic's IQueryable Structure (via LINQ?)

I'm working on a project that groups data by a "customer id". When the user logs in, they're limited to that customer and that customer only.
I'm working with SubSonic3, and what I've got looks something like this:
public IEnumerable<Models.Foo> FindFoo(int userID, string searchText, int pageIndex, int pageSize)
{
return from item in Foo.GetPaged(pageIndex, pageSize)
where (item.Name.Contains(searchText) ||
item.Description.Contains(searchText)) &&
item.CustomerID == CurrentCustomerID()
select new Models.Foo(item);
}
What I'd like to do is abstract away the item.CustomerID line, because that's going to happen for every query, without fail, so it would be simpler (and more secure) to do it in one place and guarantee it'll happen everywhere.
So, my question is: can this be done, and if so, how?
As far as subsonic generated classes are partial you can add some interface to them... Just create you're interface with CustomerID property (for example name it ICusomerEntity) and make partial for any of generated classes that will apply this interface to them... then just use the generic subsonic methods to rerieve ICustomerEntity, not the specific class..
For example you can make generic method called GetCustomerEntity with constraint T:ICustomerEntity which will return IQueriable with a bascic query comparing CustomerId with the one of logged user..
Hope it helps...

linq to sql OnLoaded() with SQL View?

I am trying to extend my Linq-to-Sql entity with a few extra properties. These are "calculated" properties based on data from the underlying SQL View. For example, think of having a Date of Birth field, which is used to calculate an extended Age field.
I tried to extend my entity class by extending the OnLoaded() method.
I get a compile time error however stating that I cannot create it. I checked the designer code for my LTS entity class, and it doesn't have a partial definition for any of the expected extension points.
I checked a few of my other LTS entity classes and they do have these extension points. The only difference I see is that the one without is loaded from a SQL View, rather than a table. Is there a way to hook into a "Loaded" event when loading from a SQL View?
TIA!
I found that I did not have a PrimaryKey specified for my Linq-to-Sql entity class. I believe without a Primary Key specified, no extension methods generated in the entity class. Once I specified a Primary Key on my LTS entity class definition (through the designer), I was able to extend the OnLoaded() event.
You can do this by means of a property. Just create a partial class with the same name as your entity. Any properties or methods that you add will automatically be part of the entity and allow to use any of its members.
Here's an example of the pattern:
public partial class [The Name of the Entity]
{
public int Age
{
get
{
return CalculateAge(this.DateOfBirth);
}
}
}
Here's some logic on how to calculate the Age (Source: Geekpedia)
public static int CalculateAge(DateTime BirthDate)
{
int YearsPassed = DateTime.Now.Year - BirthDate.Year;
// Are we before the birth date this year? If so subtract one year from the mix
if (DateTime.Now.Month < BirthDate.Month ||
(DateTime.Now.Month == BirthDate.Month && DateTime.Now.Day < BirthDate.Day))
{
YearsPassed--;
}
return YearsPassed;
}

Resources