ef core .Include()。Contains()null引用异常

时间:2017-07-12 21:12:17

标签: c# linq entity-framework-core

我的模型设置如下......

public class Model1 : IEquatable<Model1>
{
    public int Model1Id { get; set; }
    public string Name1 { get; set; }
    public Model2 Model2 { get; set; }
    public int Model2Id { get; set; }

    public bool Equals(Model1 other)
    {
        return this.Model2.Equals(other.Model2)
            && this.Name1 == other.Name1;
    }
}

public class Model2 : IEquatable<Model2>
{
    public int Model2Id { get; set; }
    public string Name2 { get; set; }

    public bool Equals(Model2 other)
    {
        return this.Name2 == other.Name2;
    }
}

public class ModelContext : DbContext
{
    public DbSet<Model1> Model1 { get; set; }
    public DbSet<Model2> Model2 { get; set; }
    public ModelContext(DbContextOptions<ModelContext> options) : base(options) { }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Model1>(b =>
        {
            b.HasOne(m1 => m1.Model2).WithMany().HasForeignKey(m1 => m1.Model2Id);
        });
    }
}

然后当我这样做时我得到一个空引用异常......

static void Main(string[] args)
{
    var myModel1 = new Model1
    {
        Name1 = "myName1",
        Model2 = new Model2
        {
            Name2 = "myName2"
        }
    };
    var connection = new SqliteConnection("DataSource=:memory:");
    connection.Open();
    try
    {
        var options = new DbContextOptionsBuilder<ModelContext>()
            .UseSqlite(connection)
            .Options;

        //create database
        using(var ctx = new ModelContext(options))
        {
            ctx.Database.EnsureCreated();
        }

        //add model objects
        using (var ctx = new ModelContext(options))
        {
            ctx.Database.EnsureCreated();
            ctx.Model1.Add(myModel1);
            ctx.SaveChanges();
        }

        //check if exists
        using(var ctx = new ModelContext(options))
        {
            //exception here
            bool isExists = ctx.Model1.Include(m1 => m1.Model2).Contains(myModel1); 
            Console.WriteLine(isExists);
        }
    }
    finally
    {
        connection.Close();
    }

    Console.ReadKey();
}

我打电话给Model2时,我m1 Includenull实例已填充ctx.Model1.Include(m1 => m1.Model2).AsEnumerable().Contains(model1); ,但它仍然是date

但如果我将AsEnumerable()添加到我的查询中,如..

strtotime

然后一切正常。

编辑:

我的问题是......为什么我需要调用AsEnumerable()?我希望它能在不调用AsEnumerable()的情况下工作。

1 个答案:

答案 0 :(得分:2)

区别在于一个是实体框架工作调用,另一个是linq到对象 实体框架不理解包含CLR对象

public void AddIfNotExists(Model1 model1)
{

    //No Need for the include this is executed in sql,  assuming the model 2 
    //property has already been included in your model1 this should work fine
    if(false == _context.Model1.Any(x => x.Name1 == model1.Name1 
                        && x.Model2.Name2 == model1.Model2.Name2))
    {
        _context.Model1.Add(model1);
    }
}

我根据你的逻辑制作了这个,但是你真的只想检查model1.id是否是model1集。但我不知道您的架构正在做什么,所以这就是您可能想要的