2009-03-17 5 views
5
나는 다음과 같은 DB를

을 삭제합니다. TagsToPosts에서 여러 항목을 다음과 같이 삭제해야합니다. 문자열을 구문 분석하여 IList<Tag> newTags을 만듭니다. 각 태그에는 이름이 있습니다. 단일 게시 (TagsToPosts.PostId == mypostid)를 가리키는 모든 TagsToPosts 항목을 삭제하고 Tag에 내 이름이 아닌 newTags을 가리키는 항목을 삭제하고 싶습니다. 예를 들어LINQ는

나는 Id = 1, 세 개의 태그 한 후이 있습니다 1 => "tag1", 2 => "tag2", 3 => "tag3"을 그리고 ManyToMany 관계 테이블 TagsToPosts은 : 1 => 1, 1 => 2, 1 => 3 은 그래서 세 가지 태그는 내 게시물에 연결되어 있습니다. 그런 다음 문자열을 구문 분석하여 새 IList<Tag> newList = new List<Tag>()을 만듭니다. newList은 다음을 포함합니다 : 0 => "tag1", 0 => "tag2". 이제 새 태그 목록에 "tag3"이라는 이름의 태그가 없기 때문에 TagsToPosts 테이블에서 세 번째 릴레이션을 제거하고 싶습니다. 그래서 나는 차이점을 찾아야한다. JOIN을 사용하여 비슷한 항목을 찾을 수 있지만 차이점을 찾는 방법은 알고 있습니까?

하나의 DB 쿼리에서 각 항목을 반복 삭제하지 않고도 삭제할 수 있습니다.

답변

0

Linq Except 연산자를 보았습니까? 예를 들어

: 당신은 LINQ - 투 - SQL이 작업을 수행 할 수

var toDelete = (from t in TagsToPost 
       select t).Except(from nt in newList 
           select nt, new TagComparer()); 

class TagComparer: IEqualityComparer<TagsToPosts> 
{ 
    public bool Equals(TagsToPosts x, TagsToPosts y) 
    { 
     return x.Tag.Equals(y.Tag, CompareOptions.Ordinal); 
    } 
} 
3

.

LINQ-to-SQL은 일괄 처리 작업에 적합하지 않습니다. 일괄 처리 작업을 수행 할 수 없으며 일괄 처리 업데이트를 수행 할 수 없으며 일괄 처리 작업을 수행 할 수 없습니다. 컬렉션의 모든 개체는 개별적으로 처리됩니다. 하나의 트랜잭션에서 모든 작업을 수행 할 수 있지만 항상 각 레코드에 대한 쿼리가 있습니다.

MSDN

더 좋은 옵션은 당신이 원하는 것을 할 것입니다 저장 프로 시저를 작성하는 것입니다.

0

PLINQO는 먼저 엔터티를 검색하지 않고 일괄 삭제 작업을 지원합니다.

VAR은 (NT를 선택 newList에서 NT에서, 새로운 TagComparer() TagsToPost 선택 t) .Except에 t에서 = 삭제)

context.Tags.Delete (삭제);

http://plinqo.com

0
당신은 클래스 필드에 의해 결정 삭제를 할 수 있습니다

내 솔루션 :

public static void DeleteByPropertyList<T, R>(List<T> listToDelete, Expression<Func<T, R>> getField, DataContext context) where T : class { 
    List<List<string>> partitionedDeletes = listToDelete.Select(d => string.Format("'{0}'", getField.Compile()(d).ToString())).ToList().Partition<string>(2000).ToList(); 
    Func<Expression<Func<T, R>>, string> GetFieldName = propertyLambda => ((MemberExpression)propertyLambda.Body).Member.Name; 
    MetaTable metaTable = context.Mapping.GetTable(typeof(T)); 
    string tableName = string.Format("{0}.{1}", metaTable.Model.DatabaseName, metaTable.TableName); 
    foreach (List<string> partitionDelete in partitionedDeletes) { 
     string statement = "delete from {0} where {1} in ({2})"; 
     statement = string.Format(statement, tableName, GetFieldName(getField), string.Join(",", partitionDelete)); 
     context.ExecuteCommand(statement); 
    } 
} 

public static IEnumerable<List<T>> Partition<T>(this IList<T> source, int size) { 
    for (int i = 0; i < Math.Ceiling(source.Count/(double)size); i++) 
    yield return new List<T>(source.Skip(size * i).Take(size)); 
} 

사용법 :

List<OrderItem> deletions = new List<OrderItem>(); 
    // populate deletions 
    LinqToSqlHelper.DeleteByPropertyList<OrderItem, long>(deletions, oi => oi.OrderItemId, context); 

그것은 단지 하나의 필드와 함께 작동하지만이 될 수있다 필드를 쉽게 합성 할 수 있도록 확장되었습니다.