Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 首先创建代码,多对多,并在关联表中添加其他字段_C#_Entity Framework_Ef Code First_Many To Many - Fatal编程技术网

C# 首先创建代码,多对多,并在关联表中添加其他字段

C# 首先创建代码,多对多,并在关联表中添加其他字段,c#,entity-framework,ef-code-first,many-to-many,C#,Entity Framework,Ef Code First,Many To Many,我有这样一个场景: public class Member { public int MemberID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public virtual ICollection<Comment> Comments { get; set; } } public class Comment {

我有这样一个场景:

public class Member
{
    public int MemberID { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    public int CommentID { get; set; }
    public string Message { get; set; }

    public virtual ICollection<Member> Members { get; set; }
}

public class MemberComment
{
    public int MemberID { get; set; }
    public int CommentID { get; set; }
    public int Something { get; set; }
    public string SomethingElse { get; set; }
}
公共类成员
{
public int MemberID{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共虚拟ICollection注释{get;set;}
}
公开课评论
{
public int CommentID{get;set;}
公共字符串消息{get;set;}
公共虚拟ICollection成员{get;set;}
}
公共类成员评论
{
public int MemberID{get;set;}
public int CommentID{get;set;}
public int Something{get;set;}
公共字符串SomethingElse{get;set;}
}

如何配置与的关联?还是有更好的方法来创建关联表?

不可能使用自定义联接表创建多对多关系。在多对多关系中,EF管理内部和隐藏的联接表。它是模型中没有实体类的表。要使用这种具有附加属性的联接表,您必须实际创建两个一对多关系。它可能是这样的:

public class Member
{
    public int MemberID { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<MemberComment> MemberComments { get; set; }
}

public class Comment
{
    public int CommentID { get; set; }
    public string Message { get; set; }

    public virtual ICollection<MemberComment> MemberComments { get; set; }
}

public class MemberComment
{
    [Key, Column(Order = 0)]
    public int MemberID { get; set; }
    [Key, Column(Order = 1)]
    public int CommentID { get; set; }

    public virtual Member Member { get; set; }
    public virtual Comment Comment { get; set; }

    public int Something { get; set; }
    public string SomethingElse { get; set; }
}
var commentsOfMembers = context.Members
    .Where(m => m.LastName == "Smith")
    .SelectMany(m => m.MemberComments.Select(mc => mc.Comment))
    .ToList();
。。。或者

var commentsOfMembers = context.MemberComments
    .Where(mc => mc.Member.LastName == "Smith")
    .Select(mc => mc.Comment)
    .ToList();
或者,要创建名为“Smith”(我们假设不止一个)的成员列表及其评论,您可以使用投影:

var membersWithComments = context.Members
    .Where(m => m.LastName == "Smith")
    .Select(m => new
    {
        Member = m,
        Comments = m.MemberComments.Select(mc => mc.Comment)
    })
    .ToList();
如果要查找
MemberId
=1的成员的所有注释:

var commentsOfMember = context.MemberComments
    .Where(mc => mc.MemberId == 1)
    .Select(mc => mc.Comment)
    .ToList();
现在,您还可以根据联接表中的属性进行筛选(这在多对多关系中是不可能的),例如:筛选成员1中属性为99的所有注释
Something

var filteredCommentsOfMember = context.MemberComments
    .Where(mc => mc.MemberId == 1 && mc.Something == 99)
    .Select(mc => mc.Comment)
    .ToList();
由于延迟加载,事情可能会变得更容易。如果您有一个已加载的
成员
,您应该能够在无需显式查询的情况下获取注释:

var commentsOfMember = member.MemberComments.Select(mc => mc.Comment);
我猜延迟加载会在幕后自动获取评论

编辑

为了好玩,我们提供了几个示例,介绍如何在此模型中添加实体和关系以及如何删除它们:

1) 创建此成员的一个成员和两个注释:

var member1 = new Member { FirstName = "Pete" };
var comment1 = new Comment { Message = "Good morning!" };
var comment2 = new Comment { Message = "Good evening!" };
var memberComment1 = new MemberComment { Member = member1, Comment = comment1,
                                         Something = 101 };
var memberComment2 = new MemberComment { Member = member1, Comment = comment2,
                                         Something = 102 };

context.MemberComments.Add(memberComment1); // will also add member1 and comment1
context.MemberComments.Add(memberComment2); // will also add comment2

context.SaveChanges();
2) 添加member1的第三条注释:

var member1 = context.Members.Where(m => m.FirstName == "Pete")
    .SingleOrDefault();
if (member1 != null)
{
    var comment3 = new Comment { Message = "Good night!" };
    var memberComment3 = new MemberComment { Member = member1,
                                             Comment = comment3,
                                             Something = 103 };

    context.MemberComments.Add(memberComment3); // will also add comment3
    context.SaveChanges();
}
3) 创建新成员并将其与现有注释2关联:

var comment2 = context.Comments.Where(c => c.Message == "Good evening!")
    .SingleOrDefault();
if (comment2 != null)
{
    var member2 = new Member { FirstName = "Paul" };
    var memberComment4 = new MemberComment { Member = member2,
                                             Comment = comment2,
                                             Something = 201 };

    context.MemberComments.Add(memberComment4);
    context.SaveChanges();
}
4) 在现有成员2和成员3之间创建关系:

var member2 = context.Members.Where(m => m.FirstName == "Paul")
    .SingleOrDefault();
var comment3 = context.Comments.Where(c => c.Message == "Good night!")
    .SingleOrDefault();
if (member2 != null && comment3 != null)
{
    var memberComment5 = new MemberComment { Member = member2,
                                             Comment = comment3,
                                             Something = 202 };

    context.MemberComments.Add(memberComment5);
    context.SaveChanges();
}
5) 再次删除此关系:

var memberComment5 = context.MemberComments
    .Where(mc => mc.Member.FirstName == "Paul"
        && mc.Comment.Message == "Good night!")
    .SingleOrDefault();
if (memberComment5 != null)
{
    context.MemberComments.Remove(memberComment5);
    context.SaveChanges();
}
6) 删除member1及其与注释的所有关系:

var member1 = context.Members.Where(m => m.FirstName == "Pete")
    .SingleOrDefault();
if (member1 != null)
{
    context.Members.Remove(member1);
    context.SaveChanges();
}

这也会删除
MemberComments
中的关系,因为
MemberComments
MemberComments
之间以及
Comment
MemberComments
之间的一对多关系是按约定级联删除的。这种情况是因为
MemberComment
中的
MemberId
CommentId
被检测为
Member
Comment
导航属性的外键属性,并且由于FK属性的类型为non-nullable
int
,因此需要关系,从而最终导致级联删除设置。我认为,在这个模型中是有意义的。

我将使用fluent映射发布代码

公共类用户{
public int UserID{get;set;}
公共字符串用户名{get;set;}
公共字符串密码{get;set;}
公共ICollection用户电子邮件{get;set;}
}
公共类电子邮件{
public int EmailID{get;set;}
公共字符串地址{get;set;}
公共ICollection用户电子邮件{get;set;}
}
公共类用户电子邮件{
public int UserID{get;set;}
public int EmailID{get;set;}
公共bool IsPrimary{get;set;}
}
DbContext
派生类上,可以执行以下操作:

公共类MyContext:DbContext{
模型创建时受保护的覆盖无效(DbModelBuilder builder){
//主键
builder.Entity().HasKey(q=>q.UserID);
builder.Entity().HasKey(q=>q.EmailID);
builder.Entity().HasKey(q=>
新{
q、 UserID,q.EmailID
});
//关系
builder.Entity()
.HasRequired(t=>t.Email)
.WithMany(t=>t.useremail)
.HasForeignKey(t=>t.EmailID)
builder.Entity()
.HasRequired(t=>t.User)
.WithMany(t=>t.useremail)
.HasForeignKey(t=>t.UserID)
}
}
它的效果与另一种方法相同,即更好或更差。

这个方法是正确的,但不完整,我已经测试过了。“UserEmail”类中缺少属性:

如果有人感兴趣,我会发布我测试过的代码。 问候

使用System.Data.Entity;
使用制度;
使用System.Collections.Generic;
使用System.ComponentModel.DataAnnotations;
使用System.ComponentModel.DataAnnotations.Schema;
使用System.Linq;
使用System.Web;
#区域示例2
公共类用户测试
{
public int UserTestID{get;set;}
公共字符串UserTestname{get;set;}
公共字符串密码{get;set;}
公共ICollection UserTestEmailTests{get;set;}
公共静态void DoSomeTest(ApplicationDbContext上下文)
{
对于(int i=0;i<5;i++)
{
var user=context.UserTest.Add(new UserTest(){UserTestname=“Test”+i});
var address=context.EmailTest.Add(new-EmailTest(){address=“address@”+i});
}
SaveChanges();
foreach(context.UserTest.Include中的var user(t=>t.UserTestEmailTests))
{
foreach(context.EmailTest中的var地址)
{
user.UserTestEmailTests.Add(新的UserTestEmailTest(){UserTest=user,EmailTest=address,n1=user.UserTestID,n2=address.EmailTestID});
}
}
SaveChanges();
}
}
公共类电子邮件测试
{
public int EmailTestID{get;set;}
公共字符串地址{get;set;}
公共ICollection UserTestEmailTests{get;set;}
}
公共类UserTestEmail
    public UserTest UserTest { get; set; }
    public EmailTest EmailTest { get; set; }
using System.Data.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

#region example2
public class UserTest
{
    public int UserTestID { get; set; }
    public string UserTestname { get; set; }
    public string Password { get; set; }

    public ICollection<UserTestEmailTest> UserTestEmailTests { get; set; }

    public static void DoSomeTest(ApplicationDbContext context)
    {

        for (int i = 0; i < 5; i++)
        {
            var user = context.UserTest.Add(new UserTest() { UserTestname = "Test" + i });
            var address = context.EmailTest.Add(new EmailTest() { Address = "address@" + i });
        }
        context.SaveChanges();

        foreach (var user in context.UserTest.Include(t => t.UserTestEmailTests))
        {
            foreach (var address in context.EmailTest)
            {
                user.UserTestEmailTests.Add(new UserTestEmailTest() { UserTest = user, EmailTest = address, n1 = user.UserTestID, n2 = address.EmailTestID });
            }
        }
        context.SaveChanges();
    }
}

public class EmailTest
{
    public int EmailTestID { get; set; }
    public string Address { get; set; }

    public ICollection<UserTestEmailTest> UserTestEmailTests { get; set; }
}

public class UserTestEmailTest
{
    public int UserTestID { get; set; }
    public UserTest UserTest { get; set; }
    public int EmailTestID { get; set; }
    public EmailTest EmailTest { get; set; }
    public int n1 { get; set; }
    public int n2 { get; set; }


    //Call this code from ApplicationDbContext.ConfigureMapping
    //and add this lines as well:
    //public System.Data.Entity.DbSet<yournamespace.UserTest> UserTest { get; set; }
    //public System.Data.Entity.DbSet<yournamespace.EmailTest> EmailTest { get; set; }
    internal static void RelateFluent(System.Data.Entity.DbModelBuilder builder)
    {
        // Primary keys
        builder.Entity<UserTest>().HasKey(q => q.UserTestID);
        builder.Entity<EmailTest>().HasKey(q => q.EmailTestID);

        builder.Entity<UserTestEmailTest>().HasKey(q =>
            new
            {
                q.UserTestID,
                q.EmailTestID
            });

        // Relationships
        builder.Entity<UserTestEmailTest>()
            .HasRequired(t => t.EmailTest)
            .WithMany(t => t.UserTestEmailTests)
            .HasForeignKey(t => t.EmailTestID);

        builder.Entity<UserTestEmailTest>()
            .HasRequired(t => t.UserTest)
            .WithMany(t => t.UserTestEmailTests)
            .HasForeignKey(t => t.UserTestID);
    }
}
#endregion
public class Member
{
    public int MemberID { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }
    public virtual ICollection<MemberCommentView> MemberComments { get; set; }
}

public class Comment
{
    public int CommentID { get; set; }
    public string Message { get; set; }

    public virtual ICollection<Member> Members { get; set; }
    public virtual ICollection<MemberCommentView> MemberComments { get; set; }
}

public class MemberCommentView
{
    public int MemberID { get; set; }
    public int CommentID { get; set; }
    public int Something { get; set; }
    public string SomethingElse { get; set; }

    public virtual Member Member { get; set; }
    public virtual Comment Comment { get; set; }
}
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;

public class MemberConfiguration : EntityTypeConfiguration<Member>
{
    public MemberConfiguration()
    {
        HasKey(x => x.MemberID);

        Property(x => x.MemberID).HasColumnType("int").IsRequired();
        Property(x => x.FirstName).HasColumnType("varchar(512)");
        Property(x => x.LastName).HasColumnType("varchar(512)")

        // configure many-to-many through internal EF EntitySet
        HasMany(s => s.Comments)
            .WithMany(c => c.Members)
            .Map(cs =>
            {
                cs.ToTable("MemberComment");
                cs.MapLeftKey("MemberID");
                cs.MapRightKey("CommentID");
            });
    }
}

public class CommentConfiguration : EntityTypeConfiguration<Comment>
{
    public CommentConfiguration()
    {
        HasKey(x => x.CommentID);

        Property(x => x.CommentID).HasColumnType("int").IsRequired();
        Property(x => x.Message).HasColumnType("varchar(max)");
    }
}

public class MemberCommentViewConfiguration : EntityTypeConfiguration<MemberCommentView>
{
    public MemberCommentViewConfiguration()
    {
        ToTable("MemberCommentView");
        HasKey(x => new { x.MemberID, x.CommentID });

        Property(x => x.MemberID).HasColumnType("int").IsRequired();
        Property(x => x.CommentID).HasColumnType("int").IsRequired();
        Property(x => x.Something).HasColumnType("int");
        Property(x => x.SomethingElse).HasColumnType("varchar(max)");

        // configure one-to-many targeting the Join Table view
        // making all of its properties available
        HasRequired(a => a.Member).WithMany(b => b.MemberComments);
        HasRequired(a => a.Comment).WithMany(b => b.MemberComments);
    }
}
using System.Data.Entity;

public class MyContext : DbContext
{
    public DbSet<Member> Members { get; set; }
    public DbSet<Comment> Comments { get; set; }
    public DbSet<MemberCommentView> MemberComments { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new MemberConfiguration());
        modelBuilder.Configurations.Add(new CommentConfiguration());
        modelBuilder.Configurations.Add(new MemberCommentViewConfiguration());

        OnModelCreatingPartial(modelBuilder);
     }
}
var commentsOfMembers = context.Members
    .Where(m => m.LastName == "Smith")
    .SelectMany(m => m.MemberComments.Select(mc => mc.Comment))
    .ToList();
var commentsOfMembers = context.Members
    .Where(m => m.LastName == "Smith")
    .SelectMany(m => m.Comments)
    .ToList();
var membersWithComments = context.Members
    .Where(m => m.LastName == "Smith")
    .Select(m => new
    {
        Member = m,
        Comments = m.MemberComments.Select(mc => mc.Comment)
    })
    .ToList();
var membersWithComments = context.Members
    .Where(m => m.LastName == "Smith")
    .Select(m => new
    {
        Member = m,
        m.Comments
    })
        .ToList();
var comment = ... // assume comment from member John Smith
var member = ... // assume member John Smith

member.Comments.Remove(comment);
var member = context.Members
    .Where(m => m.FirstName == "John", m.LastName == "Smith")
    .Include(m => m.Comments);