简体   繁体   中英

How can I optimize these two code snippits that does DB operations, for better performance?

I have a few methods that could be better optimized and it would be very helpfull if someone could explain the solutions aswell. I am using ASP.NET MVC 4 with Entity-framework.

First I have this method:

    //gets all the items by id
    var GetAllItems = re.GetAllWorldNewsByID();

    // loops through all items
    foreach (var newsitemz in GetAllItems)
    {
        if (newsitemz.Date <= DateTime.Now.AddDays(-2))
        {
            re.DeleteNews(newsitemz);
            re.save();
        }

    }

How can I change this deletion loop to be a single delete from News where Date <= @twodaysold ? I guess it would give better performance if I did that.

This method is inside my repository file that is used alot in my project.

public void AddNews(News news)
{
    var exists = db.News.Any(x => x.Title == news.Title);

     if (exists == false)
    {
        db.News.AddObject(news);
    }
    else
    {
        db.News.DeleteObject(news);
    }
}

What it does is that it checks if the news item title already exists in the database, if it does it deletes the item else it adds it. I know thats its badly made. To get it better optimized maby I should do a upset / merge . Any kind of help is appreciated.

Unfortunately EF doesn't support set based operations natively, although it is something they would like to add in at some stage, (feel free to add your two cents around this here http://entityframework.codeplex.com/discussions/376901 )

There is however an extension which does add support for set based deletes, but im not too sure about the performance of this method, it would be worth your while benchmarking before and after trying this. https://github.com/loresoft/EntityFramework.Extended

The other key thing to note is that you could drastically improve performance by performing SaveChanges only once, this means that EF will push it all to the DB at once and only have to wait for one roundtrip to the database server. eg

foreach (var newsitemz in GetAllItems)
{
    if (newsitemz.Date <= DateTime.Now.AddDays(-2))
    {
        re.DeleteNews(newsitemz);   
    }
    re.save(); //assuming this is basically context.SaveChanges()

}

You can use the RemoveAll() method to delete all or selected items:

DeleteNews(x => x.Date <= DateTime.Now.AddDays(-2));

To do this you have to change your model a bit and have the DeleteNews() method accepts a predicate as a parameter. Then use this code in the method.

It should be like:

public void DeleteNews(Predicate<News> item)
{
    //myList is list of News
    myList.RemoveAll(item);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM