M
M
MIsternik2016-02-21 12:27:20
ASP.NET
MIsternik, 2016-02-21 12:27:20

Entity Framework communication of elements of one table, chyadnt?

There is some table:

[Table("tags")]
    public class Tag
    {
        [ScaffoldColumn(true)]
        [StringLength(60)]
        [Column("id")]
        public string Id { get; set; }

        /* другие поля */

        public virtual ICollection<Tag> ParentTags { get; set; }
        public virtual ICollection<Tag> ChildTags { get; set; }
    }

You need to associate one element with another as many to many. There is a tags_relations table for this :
parent_tag_id character varying(60) NOT NULL,
child_tag_id character varying(60) NOT NULL,

and a description of the connection:
modelBuilder.Entity<Tag>()
                .HasMany<Tag>(a => a.ParentTags)
                .WithMany(a => a.ChildTags)
                .Map(tt =>
                {
                    tt.MapLeftKey("parent_tag_id");
                    tt.MapRightKey("child_tag_id");
                    tt.ToTable("tags_relations");
                });

When saving in the controller method, there are no exceptions, everything is OK:
public ActionResult Edit([Bind(Include ="Id,Title,Visible,Description")] Tag tag,string[] ParentTags)
        {
            if (ModelState.IsValid)
            {
                var parentTags = db.Tags.Where(a => ParentTags.Contains(a.Id)).ToList<Tag>();
                tag.ParentTags = parentTags;
                db.Entry(tag).State = EntityState.Modified;
                
                db.SaveChanges();
            }
            var tags = db.Tags.Where(a => a.Visible == false).Select(c => new {
                Id = c.Id,
                Title = c.Title
            }).ToList();
            ViewBag.Tags = new MultiSelectList(tags, "Id", "Title");

            return View(tag);
        }

But no records appear in the tags_relations table .
What am I doing wrong?)
Another question, how can I track the query generated by EF?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
MIsternik, 2016-02-21
@MIsternik

Attention answer! =)
Logging requests to the database helped to localize the cause.
Since I'm using NLog, it's done like this:

// Добавляем объект логгера в контроллер
private static Logger logger = LogManager.GetCurrentClassLogger();

// в самом методе, чтобы отслеживать запросы из него, добавляем:
db.Database.Log = (a) => logger.Info(a);

That's it, requests are written to the file described in the NLog settings.
The main problem was solved by changing the controller code from
if (ModelState.IsValid)
{
    var parentTags = db.Tags.Where(a => ParentTags.Contains(a.Id)).ToList<Tag>();
    tag.ParentTags = parentTags;
    db.Entry(tag).State = EntityState.Modified;
                
    db.SaveChanges();
}

on the
if (ModelState.IsValid)
{
    var parentTags = db.Tags.Where(a => ParentTags.Contains(a.Id)).ToList<Tag>();
                
    db.Entry(tag).State = EntityState.Modified;
    // перенесли добавление под предыдущую строку и добавляем так, а не приравниванием.
    parentTags.ForEach(a => tag.ParentTags.Add(a));
    db.SaveChanges();
}

E
eRKa, 2016-02-21
@kttotto

To see what request the Entity forms, in the config, in the entity section, you need to add
<

<interceptors>
      <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
        <parameters>
          <parameter value="C:\temp\LogOutput.txt" />
          <parameter value="true" type="System.Boolean" />
        </parameters>
      </interceptor>
    </interceptors>

And how strange you establish a connection. Tie the table on itself? Specifying a relationship for a table, you must specify in which table there will be a foreign key to your entity. In general, mapping in this form will not work.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question