实体框架多对多列表关联

时间:2014-02-26 03:46:28

标签: c# entity-framework

我有以下类(我只显示重要的属性):

public class TypeLocation
{
    [Key]
    public int Id {get; set;}
    public string Country {get; set;}
    public string State {get; set;}
    public string County {get; set;}
    public string City {get; set;}

    public List<Offer> Offers {get; set; }
    public TypeLocation()
    {
        this.Offers = new List<Offer>();
    }
}

public class Offer
{
    public int Id { get; set; }

    public ICollection<TypeLocation> LocationsToPublish { get; set; }
}

这会在数据库中创建以下内容:

Database Schema

我的问题/问题

TypeLocations表预先填充了国家/州/县/城市记录的静态列表,其中一个或多个可以与LocationsToPublish属性中的商品相关联。当我尝试添加位置时,使用以下代码,Entity Framework在TypeLocation表中添加一条新记录,然后通过在OfferTypeLocations表中添加记录来建立关联。

    public static bool AddPublishLocation(int id, List<TypeLocation> locations)
    {
        try
        {
            using (AppDbContext db = new AppDbContext())
            {
                Offer Offer = db.Offers
                    .Include("LocationsToPublish")
                    .Where(u => u.Id == id)
                    .FirstOrDefault<Offer>();

                //Add new locations
                foreach (TypeLocation loc in locations)
                {
                    Offer.LocationsToPublish.Add(loc);
                }
                db.SaveChanges();
            }
            return true;
        }
        catch
        {
            return false;
        }
    }

我不希望在TypeLocations表中添加新记录,只是在OfferTypeLocations表中创建关联的关系记录。对我做错了什么的想法?

解决方案

感谢下面回答的@Mick,我找到了解决方案。

    public static bool AddPublishLocation(int id, List<TypeLocation> locations)
    {
        try
        {
            using (AppDbContext db = new AppDbContext())
            {
                Offer Offer = db.Offers
                    .Include("LocationsToPublish")
                    .Where(u => u.Id == id)
                    .FirstOrDefault<Offer>();

                //Add new locations
                foreach (TypeLocation loc in locations)
                {
                    //SOLUTION
                    TypeLocation ExistingLoc = db.AppLocations.Where(l => l.Id == loc.Id).FirstOrDefault<TypeLocation>();

                    Offer.LocationsToPublish.Add(loc);
                }
                db.SaveChanges();
            }
            return true;
        }
        catch
        {
            return false;
        }
    }

使用现有的AppDbContext,我从TypeLocations表中检索现有记录(此处标识为AppLocations),然后将其添加到LocationsToPublish实体。

关键是我要使用当前的AppDbContext(用Using()语句包装)来完成所有工作。此上下文之外的任何数据都是纯信息性的,用于协助在AppDbContext上下文中发生的记录查找或创建。我希望这是有道理的。

1 个答案:

答案 0 :(得分:0)

TypeLocations是从不同的AppDbContext加载的,它们被认为是您在方法中构建的AppDbContext中的新实体。修复: -

  1. 假设位置已从方法之外的AppDbContext实例中分离,您可以将这些实体附加到新上下文。 OR
  2. 传入用于将位置加载到AddPublishLocation方法的AppDbContext。
  3. 我选择2: -

    public static bool AddPublishLocation(AppDbContext db, int id, List<TypeLocation> locations)
    {
        try
        {
            Offer Offer = db.Offers
                .Include("LocationsToPublish")
                .Where(u => u.Id == id)
                .FirstOrDefault<Offer>();
    
            //Add new locations
            foreach (TypeLocation loc in locations)
            {
                Offer.LocationsToPublish.Add(loc);
            }
            db.SaveChanges();
            return true;
        }
        catch
        {
            return false;
        }
    }