문제

EF를 사용하여 ASP.NET으로 엔티티를 업데이트하려고합니다. 엔티티를 만들고 속성을 설정 한 다음 ID가있는 별도의 레이어에서 EF로 다시 전달하여 변경 사항을 적용 할 수 있습니다. UI 컨트롤에 묶여있을 때 엔티티의 ID 만 저장하기 때문에이 작업을 수행하고 있습니다.

모든 것은 표준 속성에 대해 작동하지만 제품 (관련 엔티티)의 범주를 업데이트 할 수는 없습니다. EntityKey, EntityReference 및 기타 몇 가지를 시도했지만 카테고리 ID는 저장되지 않았습니다. 이것이 내가 가진 것입니다.

Product product = new Product();
product.CategoryReference.EntityKey = new EntityKey("ShopEntities.Categories", "CategoryID", categoryId);
product.Name = txtName.Text.Trim();
... other properties
StockControlDAL.EditProduct(productId, product);

public static void EditProduct(int productId, Product product) {
 using(var context = new ShopEntities()) {
     var key = new EntityKey("ShopEntities.Products", "ProductID", productId);
     context.Attach(new Product() { ProductID = productId, EntityKey = key });
     context.AcceptAllChanges();
     product.EntityKey = key;
     product.ProductID = productId;
     context.ApplyPropertyChanges("ShopEntities.Products", product);
     context.SaveChanges();
 }
}

EF를 정말로 사용하고 싶지만 ASP.NET과 함께 사용하는 데 몇 가지 문제가있는 것 같습니다.

도움이 되었습니까?

해결책

이것은이 질문에 대한 답변입니다 엔티티 프레임 워크가 장착 된 강력한 ASP.NET MVC

context.AttachTo(product.GetType().Name, product);
ObjectStateManager stateMgr = context.ObjectStateManager;
ObjectStateEntry stateEntry = stateMgr.GetObjectStateEntry(model);
stateEntry.SetModified();
context.SaveChanges();

시도해 보셨습니까?

업데이트, 코드 상단이 작동하지 않습니다

이것은 내가 사용한 작은 확장 속성이므로 다음 코드 블록이 이해하기 쉽습니다.

public partial class Product
{
    public int? CategoryID
    {
        set
        {  
           CategoryReference.EntityKey = new EntityKey("ShopEntities.Categories", "CategoryID", value);
        }
        get
        {
            if (CategoryReference.EntityKey == null)
                return null;

            if (CategoryReference.EntityKey.EntityKeyValues.Count() > 0)
                return (int)CategoryReference.EntityKey.EntityKeyValues[0].Value;
            else
                return null;
        }
    }
}

그리고 그것은 저를 위해 일했습니다 (이번에는 확실히) :

System.Data.EntityKey key = new System.Data.EntityKey("ShopEntities.Products", "ProductID", productId);
        object originalItem;   

        product.EntityKey = key;
        if (context.TryGetObjectByKey(key, out originalItem))
        {
            if (originalItem is EntityObject &&
                ((EntityObject)originalItem).EntityState != System.Data.EntityState.Added)
            {
                Product origProduct = originalItem as Product;   
                origProduct.CategoryID == product.CategoryID;//set foreign key again to change the relationship status           
                context.ApplyPropertyChanges(
                    key.EntitySetName, product);

            }
        }context.SaveChanges();

확실히 그것은 해킹 된 것 같습니다. 그 이유는 EF 관계가 엔티티 (수정, 추가, 삭제)로 지위를 가지기 때문에 해당 상태에 따라 EF가 많은 관계가있는 경우 외국 키의 값을 변경하거나 행을 삭제하기 때문입니다. 어떤 이유로 든 (이유를 알지 못) 관계 상태는 속성 상태와 동일하게 변경되지 않습니다. 그렇기 때문에 관계 상태를 변경하기 위해 OriginalItem에서 CategoryReference.EntityKey를 설정해야했습니다.

다른 팁

이것이 실패한 이유는 두 배입니다.

  1. 참조 (IE Product.category)를 업데이트하려면 상황에 원래 참조 값도 있어야합니다.
  2. ApplyPropertyChanges (...)는 엔티티의 일반 / 스칼라 특성에만 적용되며, 참조는 변경되지 않습니다.

그래서 나는 이와 같은 일을 할 것입니다 (이 코드는이 코드가라는 트릭을 많이 사용합니다. 스터브 엔티티 EntityKeys와 함께 멍청이를 피하려면)

Product product = new Product();
// Use a stub because it is much easier.
product.Category = new Category {CategoryID = selectedCategoryID};
product.Name = txtName.Text.Trim();
... other properties

StockControlDAL.EditProduct(productId, originalCategoryID);


public static void EditProduct(Product product, int originalCategoryID ) {
 using(var context = new ShopEntities()) 
 {
     // Attach a stub entity (and stub related entity)
     var databaseProduct = new Product { 
             ProductID = product.ProductID, 
             Category = new Category {CategoryID = originalCategoryID}
         };
     context.AttachTo("Products", databaseProduct);

     // Okay everything is now in the original state
     // NOTE: No need to call AcceptAllChanges() etc, because 
     // Attach puts things into ObjectContext in the unchanged state

     // Copy the scalar properties across from updated product 
     // into databaseProduct in the ObjectContext
     context.ApplyPropertyChanges("ShopEntities.Products", product);

     // Need to attach the updated Category and modify the 
     // databaseProduct.Category but only if the Category has changed. 
     // Again using a stub.
     if (databaseProduct.Category.CategoryID != product.Category.CategoryID)
     {
         var newlySelectedCategory = 
                 new Category {
                     CategoryID = product.Category.CategoryID
                 };

         context.AttachTo("Categories", newlySelectedCategory)

         databaseProduct.Category = newlySelectedCategory;

     }

     context.SaveChanges();
 }
}

오타가 없다고 가정하면 작업을 수행합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top