简体   繁体   English

如何检查集合的两个实体条目是否相同

[英]How to check if two entity entries of a collection are the same

I'm trying to do a generic method to update Entity Framework collections, one to many. 我试图做一个通用的方法来更新实体框架集合,一对多。 I did this method, but i'm having a problem, when i try to verify, if the element in the new collection already exists in the old one. 我做了这种方法,但是当我尝试验证新集合中的元素是否已经存在于旧集合中时,我遇到了问题。 If exists, i have to update it, rather then remove and add it again. 如果存在,我必须对其进行更新,而不是删除并再次添加。

The code is this: 代码是这样的:

public TEntity UpdateCollection<TEntity, TChildren>(myappContext dbContext, TEntity parentObject, Expression<Func<TEntity, 
            ICollection<TChildren>>> propertyExpression, ICollection<TChildren> objectChilren) where TEntity : class where TChildren : class
        {

            var parentEntityObject = dbContext.Entry<TEntity>(parentObject);
            List<TChildren> originalChildrenData = parentEntityObject.Collection(propertyExpression).CurrentValue.ToList();

            // Updating or removing existing items
            foreach (var originalItem in originalChildrenData)
            {
                // Where the problem is: If entry was just modified, i have to update.
                var newItem = objectChilren.FirstOrDefault(x => x == originalItem);
                if (newItem != null)
                {
                    dbContext.Entry<TChildren>(originalItem).CurrentValues.SetValues(newItem);
                    dbContext.Entry<TChildren>(originalItem).State = System.Data.EntityState.Modified;
                }
                else
                {
                    dbContext.Entry<TChildren>(originalItem).State = System.Data.EntityState.Deleted;
                }
            }

            // Adding new items
            foreach(var newItem in objectChilren.Except(originalChildrenData)){
                parentEntityObject.Collection(propertyExpression).CurrentValue.Add(newItem);
            }

            parentEntityObject.State = System.Data.EntityState.Modified;
            return parentEntityObject.Entity;
        }

Instead of try to check with: 而不是尝试检查:

var newItem = objectChilren.FirstOrDefault(x => x == originalItem);
                    if (newItem != null)

I also tryed with: 我也尝试过:

var newItem = this.Set<TChildren>().Local.FirstOrDefault(x => x == originalItem);

But also doesn't work, always returns null. 但也不起作用,总是返回null。 I have to get the corresponding entry and only update it. 我必须获取相应的条目并仅对其进行更新。

If it's not possible, there is another generic way to update collections "one to many"? 如果不可能,还有另一种通用的方法可以“一对多”更新集合吗?

I did it, comparing the key property from my collection, as Magnus suggested, like this: 我做到了,就像Magnus所建议的那样,比较了我收藏中的关键属性,如下所示:

public TEntity UpdateCollection<TEntity, TChildren>(myappContext dbContext, TEntity parentObject, Expression<Func<TEntity, 
            ICollection<TChildren>>> propertyExpression, ICollection<TChildren> objectChilren) where TEntity : class where TChildren : class
        {

            var parentEntityObject = dbContext.Entry<TEntity>(parentObject);
            List<TChildren> originalChildrenData = parentEntityObject.Collection(propertyExpression).CurrentValue.ToList();

            // Get key name
            var entityKeyName = GetKeyName(dbContext, originalChildrenData.Union(objectChilren).First());

            // Updating or removing existing items
            foreach (var originalItem in originalChildrenData)
            {

                var originalValueKey = originalItem.GetType().GetProperty(entityKeyName).GetValue(originalItem, null);
                var itemCompareExpression = GetCompareExpression<TChildren>(entityKeyName, originalValueKey);

                // If entry was just modified, i have to update.
                var newItem = objectChilren.FirstOrDefault(itemCompareExpression.Compile());
                if (newItem != null)
                {
                    dbContext.Entry<TChildren>(originalItem).CurrentValues.SetValues(newItem);
                    dbContext.Entry<TChildren>(originalItem).State = System.Data.EntityState.Modified;
                    // Remove item, because only 'new items' will be added after this loop
                    objectChilren.Remove(newItem);
                }
                else
                {
                    dbContext.Entry<TChildren>(originalItem).State = System.Data.EntityState.Deleted;
                }
            }

            // Adding new items
            foreach(var newItem in objectChilren)
            {
                parentEntityObject.Collection(propertyExpression).CurrentValue.Add(newItem);
            }

            parentEntityObject.State = System.Data.EntityState.Modified;
            return parentEntityObject.Entity;
        }

Methods called: 方法称为:

public string GetKeyName<TEntity>(myappContext dbContext, TEntity entity) where TEntity : class
        {
            ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
            ObjectSet<TEntity> set = objectContext.CreateObjectSet<TEntity>();
            return set.EntitySet.ElementType.KeyMembers.FirstOrDefault().Name;
        }

        public Expression<Func<TEntity, bool>> GetCompareExpression<TEntity>(string keyName, object value) where TEntity : class
        {
            var parameter = Expression.Parameter(typeof(TEntity), "x");
            var property = Expression.Property(parameter, keyName);
            var method = property.Type.GetMethod("Equals", new[] { property.Type });
            var convertedValue = Convert.ChangeType(value, property.Type);
            var expression = Expression.Call(property, method, Expression.Constant(convertedValue));

            return Expression.Lambda<Func<TEntity, bool>>(expression, parameter);
        }

As all my entities only have one key, i just used "First" on "GetKeyName", but it returns all keys, if necessary. 由于我所有的实体只有一个键,因此我只在“ GetKeyName”上使用了“ First”,但如有必要,它将返回所有键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何递归检查实体是否具有同一实体的子集合? - How to recursively check if the entity has a collection of children of that same entity? 同一实体的多对多集合,具有双向关系 - Many-to-many collection of same entity, with two-way relationship 如何声明两个包含相同数据的集合 - How to assert two collection that contains same data 如何检查带有LINQ to Entities的另一个集合中是否存在实体的子集合的项目? - How can I check whether an item of an Entity's child collection exists in another collection with LINQ to Entities? 限制集合以仅检索只读实体的最近条目 - Limit collection to retrieve only recent entries for readonly entity 如何使用LINQ(C#)连接两个集合并将集合作为一个实体转置 - How to join two collection and transpose a collection as an entity using LINQ (c#) 如何检查两个词典是否包含相同的值? - How to check if two dictionaries contain the same values? 如何检查两个字符串的长度相同? - How to check if two string are of the same length? 如何将两个外键设置为同一父列(实体框架) - How to setup two foreign keys to the same parent column (Entity Framework) 如何在实体framefork 6中映射同一类的两个列表属性 - How map Two List properties of same class in Entity framefork 6
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM